1

likeで終わる単語を一致させ#たい

こんにちはこんにちは# 世界#

境界線を使ってみた

\b\w+#\b

単語境界ではないと思っ\bていたのですが、今回の場合はそうではないようです


驚くべきことに

\b\w+#\B

マッチ!

では、なぜ\Bここで機能し、機能しないのですか!また、この場合\bは機能しないのはなぜですか!\b


注: はい、使用できますが、この場合に機能する\b\w+#(?=\s|$)理由を知りたいです!\B

4

3 に答える 3

6

単語境界の定義\b

word での単語境界の定義は不正確です。先読み後読み、略語文字クラスで単語境界を定義しましょう\w

単語境界\bは次と同等です。

(?:(?<!\w)(?=\w)|(?<=\w)(?!\w))

つまり:

  • すぐ前には (少なくとも) 単語の文字である文字がありすぐ後ろには単語の文字が見つかりません (文字が単語の文字ではないか、文字列の先頭です)。

    また

  • すぐ後ろには (少なくとも) 単語の文字である文字がありすぐ前には単語の文字が見つかりません (文字が単語の文字ではないか、文字列の末尾です)。

(これが XOR の論理積と論理和への展開にいかに似ているかに注意してください)

非単語境界\Bは次と同等です。

(?:(?<!\w)(?!\w)|(?<=\w)(?=\w))

つまり:

  • すぐ前も後ろも、単語の文字が見つかりません。この定義では、空の文字列は非単語境界と見なされることに注意してください。

    また

  • 真正面と真後ろ、両脇は単語文字。この分岐には 2 文字が必要であることに注意してください。つまり、空でない文字列の先頭または末尾に配置することはできません。

(これが XNOR の論理積と論理和への拡張にいかに類似しているかに注意してください)。

単語の文字の定義\w

\bandの定義は1の定義\Bに依存するため、特定のドキュメントを参照して、何が一致するかを正確に知る必要があります。\w\w

1正規表現フレーバーのほとんどは、に\b基づいて定義され\wます。Java [Point 9]除いて 、デフォルト モードでは ASCII のみで部分的に Unicode を認識します。\w\b

  • JavaScriptでは[A-Za-z0-9_]、デフォルト モードになります。

  • .NETでは、\wデフォルトで に一致し、 ECMAScript オプション[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\P{Lm}\p{Nd}\p{Pc}]が指定されている場合は JavaScript と同じ動作になります。PCカテゴリの文字一覧では、スペース(ASCII32)が入っていないことだけは知っておいてください。

質問への回答

上記の定義により、質問への回答は簡単になります。

"hi hello# world#"

ではhello#、後ろ#はスペース ( U+0020、Zs カテゴリ) であり、単語文字で#はなく、単語文字自体ではありません ( Unicode では、Po カテゴリにあります)。したがって、\Bここで一致できます。この場合、ブランチ(?<!\w)(?!\w)が使用されます。

ではworld#、後ろ#は文字列の終わりです。は単語文字ではなく、#前方に単語文字を見つけることができない (そこには何もない) ため、\Bの直後の空の文字列に一致する可能性があり#ます。(?<!\w)(?!\w)この場合もブランチが使用されます。

補遺

Alan Moore は、コメントで非常に優れた要約を提供しています。

覚えておくべき重要な点は、正規表現は読み取れないということです。つまり、彼らは言葉ではなく、文字だけを扱います。が単語の先頭または末尾に一致すると言うとき\b、人間が行うように、単語を識別してからその終点を探すという意味ではありません。見えるのは、現在位置の前の文字と現在位置のの文字だけです。したがって、\b現在の位置単語境界である可能性があることのみを示します。両側のキャラクターがどうあるべきかを確認するのはあなた次第です。

于 2013-05-18T12:59:52.987 に答える
1

#スペースはどちらも非単語文字であるため、それらの間の目に見えない境界は単語の境界ではありません。したがって\b、一致せず、\B一致します。

于 2013-05-18T10:47:38.497 に答える