正規表現のリファレンスを読んでいて、次のことを考えています。と ??文字。それらの有用性をいくつかの例で説明していただけますか? 私はそれらを十分に理解していません。
ありがとうございました
正規表現のリファレンスを読んでいて、次のことを考えています。と ??文字。それらの有用性をいくつかの例で説明していただけますか? 私はそれらを十分に理解していません。
ありがとうございました
これは素晴らしい質問であり、私??
自身が遅延量指定子の要点を理解するのにしばらく時間がかかりました。
の有用性?
は簡単に理解できます。http
と の両方を見つけたい場合はhttps
、次のようなパターンを使用できます。
https?
このパターンは、s
オプションになるため、両方の入力に一致します。
??
はより微妙です。通常は同じことを?
行います。「この入力はこの正規表現を満たしていますか?」と尋ねても、真/偽の結果は変わりません。代わりに、「この入力のどの部分がこの正規表現に一致し、どの部分がどのグループに属しているか?」という質問に関連しています。入力が複数の方法でパターンを満たすことができる場合、エンジンは?
vs. ??
(または*
vs. *?
、または+
vs. +?
) に基づいてグループ化する方法を決定します。
検証して解析したい一連の入力があるとします。これは(確かにばかげた)例です:
Input:
http123
https456
httpsomething
Expected result:
Pass/Fail Group 1 Group 2
Pass http 123
Pass https 456
Pass http something
最初に頭に浮かぶことを試してみてください。これは次のとおりです。
^(http)([a-z\d]+)$
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass http s456 No
Pass http something Yes
それらはすべてパスしますが456
、グループ 2 のみが必要なため、2 番目の結果セットは使用できません。
よし、やり直そう。グループ 2 は文字または数字にすることができますが、両方にすることはできません。
(https?)([a-z]+|\d+)
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass https 456 Yes
Pass https omething No
?
これで 2 番目の入力は問題ありませんが、3 番目の入力はデフォルトで貪欲であるため、間違ってグループ化されています (これ+
もそうですが、?
最初に来ました)。がまたはのs
一部であるかどうかを判断するとき、結果がいずれかのパスである場合、正規表現エンジンは常に左側のものを選択します。したがって、グループ 1 がそれを吸ったので、グループ 2 が負けます。https?
[a-z]+|\d+
s
これを修正するには、1 つの小さな変更を加えます。
(https??)([a-z]+|\d+)$
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass https 456 Yes
Pass http something Yes
基本的に、これは次のことを意味します。「必要に応じて一致https
しますが、グループ 1 がhttp
. s
エンジンは、 が の一部として機能する可能性があることを認識する[a-z]+|\d+
ため、それをグループ 2 に配置することを優先します。
との主な違いは?
、??
その怠惰性に関するものです。??
怠け者で?
はありません。
たとえば、テキスト本文で "car" という単語を検索したいが、単数形の "car" だけに限定したくないとします。また、複数形の「車」に対しても一致させたいと考えています。
これが例文です:
I own three cars.
ここで、"car" という単語に一致させたい場合、文字列 "car" のみを取得し??
たい場合は、次のように遅延を使用します。
cars??
これは、「単語 car または cars を探してください。どちらかが見つかった場合は、戻るcar
だけでそれ以上は何もありません」という意味です。
ここで、同じ単語 (「car」または「cars」)と一致させたい場合、一致全体を返したい場合は、次の?
ように非遅延を使用します。
cars?
これは、「単語 car または cars を探し、見つけたものは何でも car または cars のいずれかを返す」ことを示しています。
コンピュータ プログラミングの世界では、レイジーとは一般に「必要なだけ評価する」ことを意味します。そのため、レイジー??
は一致を作成するために必要な量だけを返します。「cars」の「s」はオプションであるため、返さないでください。反対に、非遅延 (欲張りと呼ばれることもあります) 操作は可能な限り評価するため?
、オプションの "s" を含むすべての一致が返されます。
個人的に?
は、他の正規表現演算子 ( *
and+
演算子など) を単純な文字のオプション性よりも頻繁に使用する方法として、YMMV を使用していることに気付きました。
例として Clojure で実装された上記を次に示します。
(re-find #"cars??" "I own three cars.")
;=> "car"
(re-find #"cars?" "I own three cars.")
;=> "cars"
itemre-find
は、最初の引数を正規表現として受け取り#"cars??"
、2 番目の引数で見つかった最初の一致を返す関数です。"I own three cars."
?
前の項目 (文字、文字クラス、グループ) をオプションにするだけです。
colou?r
「色」と「色」に一致
(swimming )?pool
「プール」と「プール」にマッチ
??
は同じですが、怠け者でもあるため、可能であればそのアイテムは除外されます。それらのドキュメントが指摘するように、?? 実際にはまれです。私はそれを使用したことがありません。