正規表現について教えてください。
JavaScriptでプログラミングを行っています。
その中で文字列に対しゼロサプレスを行いたいと思い
調べた結果、正規表現を使用する以下のコードで
実現可能なことが分かりました。
val.replace(/^0+([0-9]+.*)/, "$1")
コードを記述し実行すると確かに可能なのですが
正規表現を調べてみても何故これでゼロサプレスが可能なのか
よく理解できませんでした。
申し訳ありませんが初心者でも理解できるように説明して頂けないでしょうか。
宜しくお願いします。
No.2ベストアンサー
- 回答日時:
正規表現のプロではないですが、自分なりに分解して説明してみます。
^ …文字列の先頭から
0+ …「0に一致」と「直前の文字の1回以上に一致」、あわせて「1文字以上の'0'の連続」
( …グループ化の始まり マッチした部分が$1に格納される
[0-9]+ …「'0'から'9'に一致」と「直前の文字の1回以上に一致」、あわせて「1文字以上の'0'から'9'の連続」
.* …「任意の一文字(\n以外)」と「直前の文字の0回以上に一致」、あわせて「任意の文字列」
) …グループ化の終わり
まとめると
文字列の先頭から1文字以上の'0'の連続があり、それ以降の'0'から'9'の連続と、残りの文字列が、$1に格納される
と解釈できます。
そしてマッチした部分(今回の場合は文字列全体)が、$1に置き換えられます。
マッチしなかった場合(今回の場合1文字目が0じゃない場合)は、置換が実行されず元の文字列のままになります。
No.5
- 回答日時:
#4です。
すみません、間違いがありました。
#3さんのおまけにありますが、
00などの時に、0を残さないといけないのですね・・・。失念していました。
なので、最後の2行は無視してください。
No.4
- 回答日時:
まずお手元に適当な資料を用意。
http://www.tohoho-web.com/js/string.htm#replace
http://www.tohoho-web.com/js/regexp.htm
順番に見てみると、
1. 「^0+」は「文字列先頭で1個以上の0とマッチ」
2. 「[0-9]+.*」は「1個以上の数値と以降の任意文字列」
と言えるかと思います。
Javascriptの場合、デフォルトで最大マッチなので、1の方で先頭から続く0を全てマッチさせることができます。
正規表現に含まれる括弧は、くくった順に$1, $2,...で参照できるようになります。
よってreplaceでは、第二引数で$1を指定することにより、正規表現全体にマッチした部分を、2の部分だけに置き換える、という処理が行われます。
なお、2に関しては、そんなに詳細に指定しなくても、別に「.*」でも良い気がします。
もっと言えば、replaceですので「val.replace(/^0+/, "")」のように、なくても良いと思います。
No.3
- 回答日時:
正規表現は苦手なので詳しいわけではないのですが、つたない説明を…
(だからって、他のものが得意ってわけでもないけど)
まず、正規表現の概要やメタ文字の意味などについては、以下など参照してください。
(ぐぐれば解説はたくさん見つかると思います)
http://www.site-cooler.com/kwl/javascript/15.htm
http://www.albert2005.co.jp/study/javascript/reg …
> /^0+([0-9]+.*)/
を分解して大雑把に説明すると
^0+ = 行頭が0で始まる一文字以上の連続する0
[0-9]+ = 一文字以上の連続する数字(=0~9まで)
.* = 0個(=なし)以上の文字列
() = グループを指定 (この部分が$1として参照される)
という意味になります。
要は{ 「前ゼロ部分」(「連続する数字」+「文字列」) }という部分が見つかったら、()内(=$1)に置き換える(=reolace)ということになります。(「文字列」はなくてもよい)
例として"0000123"を考えた場合、マッチすることはわかると思いますが、0 と 000123 などのように分割されてもよさそうに思えます。
しかし、正規表現の場合、+や*の指定では、なるべく長い文字列をヒットさせるというルールになっているようで、この場合先にある「^0+」に対してできるだけ長くとると「0000」が該当するように解釈されて、0000 と 123 という分割になり、"0000123"→"123"という置き換え結果になります。
"0000123.456"や"0000123E45"のような場合は、数字の後ろに小数点やEが出てきたら、最後の.*に該当しますが、この部分は「数字以外の文字が出た後の文字全部」と言い換えることができますので、結局()ブロックには前ゼロ部分以外の残り全部がマッチすることになります。
(このルールを変える表現として +? や *? などがありますが、調べてみてください)
^0+となっているので、"$0000123"みたいに先頭に記号があったり、" 0000123"のように空白があるだけでもマッチしなくなります。
おまけ
"00"の場合は、[0-9]+に対して1個以上の0がマッチの条件となるので0 と 0に分けられて、結果、0に置き換えられることになります。
"0"の場合には、^0+と[0-9]+でそれぞれ1個以上の0(または数字)がなければならないので、マッチしないことになり置き換えはおきません。(結果は"0"のまま)
多分、事前に数値であることのチェックを別途行っていると思いますが、文字列の"ID007"や"007:ID"を対象に考えてみるとそれぞれ
"ID007" → ID007 (マッチしない)
"007:ID" → 7:ID (マッチして置き換わる)
のようになります。
などと調べていたら、↓にちょっと面白い記事がありましたので、ご参考まで。
http://d.hatena.ne.jp/koseki2/20090530/JsIdiom
No.1
- 回答日時:
この正規表現の説明だけ聞いても、ふふーん となるだけで、
たいして知識にならないでしょう。参考サイトをいくつか挙げるので、
ちゃんと、自分で調べてみましょう!
http://www.site-cooler.com/kwl/javascript/15.htm
http://www.kt.rim.or.jp/~kbk/regex/regex.html
http://www.komonet.ne.jp/~perl/chap7.htm
http://www.mnet.ne.jp/~nakama/
とはいえ、お礼が欲しいから、つたない解説(うまく説明できてないかも...
val.replace(/^0+([0-9]+.*)/, "$1")
はvalの中で^0+([0-9]+.*)というパターンにマッチしたものを
([0-9]+.*)に置き換えます。 ※([0-9]+.*)が$1になります。
^0+([0-9]+.*)は「行の先頭に0が1文字以上有り、続いて0から9の文字の
どれかが1文字以上有り、続いて任意の文字が0文字以上ある」というパターン
です。
()内グループサブマッチのパターン [0-9]+.* の意味は、「0から9の文字の
どれかが1文字以上有り、続いて任意の文字が0文字以上ある」というパターン
です。 ※先の0は0+で取得されてるからこのグループには入らない
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- オープンソース csvデータのダブルクォーテーションで囲まれた文字内にあるカンマを削除したい 3 2022/09/02 15:17
- その他(プログラミング・Web制作) VB.NETの正規表現について 4 2022/04/12 16:54
- Access(アクセス) AccessVBAで任意の複数リンクテーブルをAccessVBAを動かす際に削除したいと考えておりま 1 2022/11/17 15:45
- 英語 仮定法と直接法の共存する文での使い分けの文法事項等について 1 2023/07/04 09:19
- 英語 前の文章全体を受ける関係代名詞を使った"which"で、「それだけでも~」と表現する方法について 1 2022/06/20 14:19
- 英語 関係代名詞「非制限用法」が説明する先行詞が無冠詞複数形の場合「一般的総称」と見なすことの可否について 10 2022/07/20 10:19
- 英語 関係代名詞節内の複文の可否とルールについて 1 2022/08/02 11:08
- Illustrator(イラストレーター) イラストレーターが買えない 1 2022/08/25 13:23
- 英語 「to不定詞」ではなく、「前置詞 to+名詞」しかとらない表現の規則性あるいは感覚について 1 2023/06/01 18:02
- その他(プログラミング・Web制作) テキストエディタで複数行にわたる文字列の行頭に番号を振る方法 4 2023/03/11 12:57
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
指定時間になったら、WEBサイト...
-
フォームが空欄の時にフォーム...
-
スマホ上で、左右スワイプで次...
-
プログラムがうまく動きません...
-
Colorboxがうまく設置できません
-
画面遷移を行わずに同一ページ...
-
初心者です。gulpでコンパイル...
-
console.logがどうしても2つ機...
-
Googleフォームで選択肢に応じ...
-
イラストレーター、縦中横のシ...
-
【GAS】WEBアプリでハイパーリ...
-
特定の文字列を複数抜き出した...
-
sessionStorageを調べています。
-
読み込んだQRコードをフォーム...
-
jsで質問です。 ボタンが二つ存...
-
階層別の組織図の自動作成について
-
コードレビューをお願いします。
-
セレクトボックスで配列を呼び...
-
HTMLタグに複数のクラスを設定...
-
コードレビューをお願いします。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
var exports = exports || {}; ...
-
HTMLタグに複数のクラスを設定...
-
jsで質問です。 displayプロパ...
-
画面遷移を行わずに同一ページ...
-
Googleフォームで選択肢に応じ...
-
特定の文字列を複数抜き出した...
-
フロントエンドフレームワーク...
-
変数名をどのようにつけるのが...
-
【JS】selectでchangeした時の...
-
React hooksが値を返して配列変...
-
オブジェクトから任意のプロパ...
-
指定時間になったら、WEBサイト...
-
Colorboxがうまく設置できません
-
二次元配列の中の各行の要素を...
-
読み込んだQRコードをフォーム...
-
IndexedDB を使ってファイルア...
-
HTMLで作った時報アプリが動き...
-
GASに文字列として関数を入れる...
-
GASでGoogleフォームの自動返信...
-
①入力フォーム→②確認表示画面→③...
おすすめ情報