質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

4回答

2411閲覧

正規表現の`^`や`$`などにつきまして

binzo

総合スコア12

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2015/03/20 10:58

現在、とあるソースコードを読んで学習を行っているのですが、
その中の正規表現を使用したコードにつきまして、
理解が追いつかない状況におります。

対象言語: javascript
対象ソースコード: riot.js

lang

1var regex = /^<([\w\-]+)>([^\x00]*[\w\/}]>$)?([^\x00]*?)^<\/\1>/gim; 2src.replace(regex, function(a,b,c){ /*省略*/ })

問題のコードを一部抜粋させていただきました。
コードについて補足させていただきます。
上記のコードは独自シンタックスを含んだhtmlタグのマッチに使用されています。
つまり、

lang

1<something> 2 <h3>title</h3> 3 <ul> 4 <li>list</li> 5 </ul> 6 7 // javascript code 8 var hoge = 'hoge'; 9</something>

仮に上記のような文字列だった場合に、
それぞれの部分文字列には、
1つ目 {タグ名: something}
2つ目 {<something></something>内のjavascriptを除いたhtml:

<h3>title</h3> <ul> <li>list</li> </ul> } 三つ目 {script: `var hoge = 'hoge';`} がマッチするようになっております。

問題のコードがどのような処理を担っているのかは理解できたのですが、
そこで使用されている正規表現が何故そのように記述されているのかが理解できません。
下記に理解が足らない部分を列挙させていただきます。

  • 2つ目と3つ目の部分文字列に[^\x00]が含まれていますが、具体的にはどのような文字を除くように指定されているのでしょうか?

  • 2つ目の部分文字列の最後に$が含まれていますが、これは2つ目の部分文字列が文末に存在するかの判定という認識で良いのでしょうか、また、その場合にはその後の正規表現の判定は無視されるのでしょうか?

  • 同様に後方参照の直前にある^は、文頭に後方参照が存在するという認識で良いのでしょうか?

特に、後者の2点に悩まされています。
上手く説明ができておらず、申し訳ございません。
私は今まで^$/^.*$/のようにそれぞれ先端と末端([^]は除く)でしか使用していなかったために、困惑しております。
恐らくgmのフラグが使用されていることに関係があるのではと考えているのですが、糸口が見つけられずにいます。

是非皆様のお力をお借りできればと思います。
よろしくお願いいたします。

binzo

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

自己解決

ご回答をいただいた皆様にお礼を申し上げます。
皆様のご回答を参考に再度調べなおしてみたところ、納得のいく解決にたどり着くことが出来ました。
皆様のご回答はどれも参考になり、それぞれのご意見の複合により私が求めていた解決の糸口を見つけることができたため、どなたかのご回答をベストアンサーとするのではなく、勝手ではございますが自己解決という形で質問を閉じさせていただきたいと思います。

以下にどのような形で自己解決に至ったのかの説明をさせていただきます。

まず、^,$ですが、皆様のおっしゃるようにmフラグの場合には、それぞれ直後、直前にマッチするようです。今回の正規表現では^が後方参照の前にも指定されていたため、パターン中で複数の^が存在することにより、文字列の先頭が2つ?と困惑してしまいましたが、皆様により理解することができました。
つまり、
/^<something>[^\x00]*?^<\/something>/gim
はさきほどのようなhtmlを文字列で表現した場合でいうところの

lang

1<something> 2 <h3>hoge</h3> 3</something> 4 5文字列では 6<something>\n <h3>hoge</h3>\n</something>

にマッチし、

lang

1<something> 2 <h3>hoge</h3> 3<span>foo</span></something> 4 5文字列では 6<something>\n <h3>hoge</h3>\n<span>foo</span></something>

にはマッチしないということがわかりました。
riot.jsのドキュメントにも、カスタムタグを宣言する際にはカスタムタグの前にインデントがあってはならないと記載されていたことを思い出し、その意味するところを理解することができました。

最後に[^\x00]*についてですが、
\x00は皆様がおっしゃるようにnull文字として、文字列の終端を意味するようですが、
今回の正規表現ではnull文字というよりも改行を含めた任意の一文字として使用されているようです。
(null文字以外という指定の意もあるかと思いますが。)
つまり、(\n|.)*,[\s\S]*+null文字以外のショートハンドなのではと思います。
何故[^\x00]*という表現が出てくるのかしばらく疑問でしたが、
試しに[^\x00]*.*と置き換えた時に、今までマッチしていた文字列がマッチしなくなり、
原因が改行コードにあったことにより、気がつくことができました。

それぞれを理解出来たことにより、問題の正規表現も今となってはなるほどと思うことができるようになりました。
今後同じような問題で悩む方にこの解決が何かお力になれれば幸いです。

この自己解決につきまして、「いやいや、そうじゃないよ」といったような他に指摘すべき点を見受けられたかたがいらっしゃいましたら、後学のために是非ご指摘いただけましたらと思います。

最後になりますがご回答を頂いた皆様誠にありがとうございました。

binzo

投稿2015/03/20 23:14

binzo

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

null文字の用途について調べまくったのですが出てきませんでした
http://ja.wikipedia.org/wiki/%E3%83%8C%E3%83%AB%E6%96%87%E5%AD%97
ただブラウザによっては文字化けしてしまうみたいだしそれを防いでるのかな?
(実際firefoxで試したら文字化けした)
2つ目の$はmフラグがついてるので質問どうり行ごとに判定されます
"その場合"というのが$のあとという意味なら$のあとも含まれます

調べましたが正規表現勉強中につき間違ってるかもしれません

投稿2015/03/20 16:48

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

binzo

2015/03/20 23:17

ご回答ありがとうございます。 null文字がどういったものなのか理解することができました。 urlもたいへん参考になりました、ありがとうございます。 $とmフラグにつきましても参考になり、理解することが出来ました、 ありがとうございます。 またお力をお借りしたい機会がありましたら、よろしくお願いいたします。
guest

0

正規表現^は、文字列先頭もしくは行頭(改行文字の直後)にマッチします。
正規表現$は、文字列末尾もしくは行末(改行文字の直前)にマッチします。

mフラグが指定されているときは、正規表現.が改行文字にもマッチするので、改行文字の前後にマッチするケースがよく出てきます。

\x00はNUL文字です。普通はあまり表に出てこないと思います。

投稿2015/03/20 14:59

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

binzo

2015/03/20 23:29

ご回答ありがとうございます。 正規表現`^`と正規表現`$`につきまして分かりやすいご回答ありがとうございました。 非常に参考になり、解決の糸口をつかむことができました。 また、正規表現`.`につきまして、rubyなど他の言語の中には`mフラグ`を指定した場合に改行も含む任意の一文字となる場合があるようですが、javascriptでは期待した動作にならないようです。 またお力をお借りしたい機会がありましたら、よろしくお願いいたします。
guest

0

正規表現(RegExp)
のフラグについての記載から/gimにより
全文を複数行にわたり大文字小文字問わず検索
するというフラグ指定になっているのでは?

また([^\x00]*?)は先頭にnull文字があるか、またその数は問わない、なおかつあるのかどうかわからない
という指定ですかね?
MDN/正規表現
を参考に読んでいけば恐らく読めるとは思いますが……

投稿2015/03/20 14:05

Cf_cwd

総合スコア730

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

binzo

2015/03/20 23:32

ご回答ありがとうございます。 ご指摘の通り、改行などにより複数行となった文字列全体に正規表現を適用できるようですね。 `\x00`につきましても参考とさせていただきました、ありがとうございます。 またお力をお借りしたい機会がありましたら、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問