特定の文字を含まない行の選択につてNo.35679
P_and_A さん 17/03/20 15:30
 
正規表現のについての基本的な質問なのですが

特定の文字列を含まない行を選択するのに、後方不一致を利用して下記のように指定
すればうまく行くのですが、

^(?!.*STRING).*

これは、

^.*(?!STRING).*

とするとうまく行かないのは何故なのでしょうか?

また、よく下記のような指定すると書かれているサイトが多いのですが

^(?!.*STRING).+$

これは何故でしょうか?

末尾部分が「.*」で「$」はなくても結果に代わりはない気がするのですが・・・、
こうしないと何か問題が起きるケースがあるのでしょうか?

[ ]
RE:35679 特定の文字を含まない行の選択にNo.35680
h-tom さん 17/03/20 19:12
 

h-tom です。

>^(?!.*STRING).*
>
>これは、
>
>^.*(?!STRING).*
>
>とするとうまく行かないのは何故なのでしょうか?
「^.*」でSTRINGを含む文字列にマッチするから。
正規表現は、最長一致が原則です。

>また、よく下記のような指定すると書かれているサイトが多いのですが
>
>^(?!.*STRING).+$
>
>これは何故でしょうか?
>
>末尾部分が「.*」で「$」はなくても結果に代わりはない気がするのですが・・・、
>こうしないと何か問題が起きるケースがあるのでしょうか?
「.*」と「.+」では、空行にマッチするかしないかの違いがあります。

[ ]
RE:35680 特定の文字を含まない行の選択にNo.35681
P_and_A さん 17/03/20 20:10
 
h-tomさん、ありがとうございます

>「^.*」でSTRINGを含む文字列にマッチするから。
>正規表現は、最長一致が原則です。

でも、

^.*STRING.*

だとSTRINGを含む行だけにマッチしますよね

最長原則の法則で「^.*」でSTRINGまでマッチしてしまうのであれば違う結果になる
ような気がするのですが・・・

[ ]
RE:35681 特定の文字を含まない行の選択にNo.35683
h-tom さん 17/03/20 22:05
 

h-tom です。

>最長原則の法則で「^.*」でSTRINGまでマッチしてしまうのであれば違う結果になる
>ような気がするのですが・・・

以下の文字列に対し、「^.*」で検索すると、改行の前までマッチします。
aaaaaaaaaaaaaaaaaaaaaaaaaaaSTRINGbbbbb

改行の手前にカーソルを移動して、「(?!STRING).*」で検索すると、
その位置でマッチしているから、カーソルは動きません。
(STRINGの先頭ではない、0個以上の文字にマッチしている)
(後方不一致/否定先読みは、アンカーであり、位置にマッチする)

だから、「^.*(?!STRING).*」は「特定の文字列を含まない行」にはならないです。

[ ]
RE:35683 特定の文字を含まない行の選択にNo.35684
P_and_A さん 17/03/21 09:39
 
すみません、余計に分からなくなってしまいました(;ω;)ゥ

実際の動作がそのようになっているのは分かっているので困っているわけではなく、
初歩的な正規表現のルールの理解(解釈)の問題でしかないのですが

>「^.*」で検索すると、改行の前までマッチします。

それは分かるのですが、

.*STRING とすると先頭からSTRINGまで
STRING.* とするとSTRINGから改行の前までマッチしますので

.*STRING.* でSTRINGを含む行の先頭から改行前までマッチすることについて、

>「^.*」でSTRINGを含む文字列にマッチするから。

というルールでは理解できない部分があるのですが・・・

書き方として正しくないかもしれませんが
.*(STRING).* でも結果は同じ
.*(?=STRING) ではSTRINGの前までマッチ
(?!STRING).* ではSTRINGを含むSTRINGから改行前までマッチ

.*(?=STRING).* でSTRINGを含む行全部がマッチしますので

ならば、.*(?!STRING).* とすればその逆、STRINGを含まない行全部がマッチしてく
れたらいいな、と思ったのですが、そう浅はかでもなかったようでo(__)o

(?!----)が位置を示すだけ、と言うのは最近知りましたがいまいち理解できていませ
ん・・・。(?=----)ならば理解(予想)したとおりの挙動をしますが、色々仮説を自
分なりに立てて実験してみても、(?!----)のほうはどうにも難しく・・・

ここでこのような質問を続けていいのか分かりませんが、思わず質問してしまいまし
た。

もし場違いという事であれば、この辺で・・・

もう少し自分で勉強してみます(^_^;)
ありがとうございましたm(__)m

[ ]
RE:35684 特定の文字を含まない行の選択にNo.35685
秀まるお2 さん 17/03/21 11:02
 
 正規表現の中でも、特に「後方一致/不一致」、「前方一致/不一致」は理解が
難しくて、僕自身もHmJreのプログラム作りながらいろいろバグを出しては直し
てとしていました。

 自分風に追加説明させていただきます。

> ^.*(?!STRING).*

> とするとうまく行かないのは何故なのでしょうか?

 話を単純化するために、正規表現パターンを

 ^.*(?!y).*$

 とします。つまり、「y」を含まない行にマッチさせたいのだとします。

 検索対象文字列は、「xyz」だと仮定します。

 ここで仮に、「(?!y)」が無い、「.*.*」が、どうマッチするかを考えます。
「.*」が2つあるので、それぞれについてどうマッチングするかの可能性をすべ
て考える必要あります。結果、

 最初の.*     次の.*
  ""           "xyz"
  "x"          "yz"
  "xy"         "z"
  "xyz"        ""

 の4通りのマッチの仕方がありえます。

 (?!y)があることによって、2番目の

  "x"          "yz"

 のマッチは拒否されます。しかし、他にも3通りのマッチングパターンが存在
して、結果、そっちにマッチしてしまいます。どれか1つでも抜け穴があれば、
それが最終的な結果として「マッチする」という結果になります。


 「^(?!.*y).*」の場合だと、.*が1つしか無いので、それ自体は、必ず
「xyz」全体にヒットします。そうすると、


    (?!.*y)  が、"xyz" に対してマッチしないならOK


 という単純な図式になって、うまく期待通りになります。




---------------------------------------------------------------
 っと自分で書いてみたんですが、やっぱり分かりにくいかもしれません。

[ ]
RE:35685 特定の文字を含まない行の選択にNo.35686
P_and_A さん 17/03/21 17:00
 
ありがとうございます、
なんとなく、分かった気がします!\(^o^)/

お忙しいところ、お手を煩わせてすみませんでした。

最近さらに便利な機能が分かってきまして、手放せないものとなっております。

深謝 m(__)m

[ ]