正規表現リファレンス を読んでいて、私は考えていますか?そして??文字。いくつかの例でその有用性を説明してもらえますか?私はそれらを十分に理解していません。
ありがとうございました
?
と??
の主な違いは、lazinessに関係します。 ??
はレイジーですが、?
はレイジーではありません。
テキストの本文で「車」という単語を検索したいが、単数の「車」だけに制限されたくないとしましょう。また、複数の「車」と照合する必要があります。
以下に例を示します。
I own three cars.
ここで、「car」という単語に一致させたい場合および戻り値として「car」という文字列のみを取得したい場合、次のように遅延??
を使用します。
cars??
これは、「Wordの車を探します。どちらかを見つけたら、car
を返し、それ以上は返しません」と言います。
ここで、同じ単語(「car」または「cars」)と一致させたい場合および一致するものすべてを返したいの場合、以下のように非遅延?
を使用します。
cars?
これは、「Wordの車を探して、車または車のいずれかを返します」と言います。
コンピュータプログラミングの世界では、怠zyは一般に「必要なだけ評価する」ことを意味します。したがって、怠zyな??
は、一致するために必要な量だけを返します。 「cars」の「s」はオプションであるため、返さないでください。逆に、非遅延(greedyと呼ばれることもある)操作は可能な限り評価するため、?
は、オプションの "s"を含むすべての一致を返します。
個人的には、他の正規表現演算子(?
や*
演算子など)をレイジーにする方法として+
を使用しているのは、単純な文字のオプションに使用するよりも頻繁ですが、YMMVです。
以下は、例としてClojureで実装された上記の例です。
(re-find #"cars??" "I own three cars.")
;=> "car"
(re-find #"cars?" "I own three cars.")
;=> "cars"
アイテムre-find
は、最初の引数を正規表現#"cars??"
として受け取り、2番目の引数"I own three cars."
で見つかった最初の一致を返す関数です。
これは素晴らしい質問であり、怠な??
量指定子のポイントを自分で確認するにはしばらく時間がかかりました。
?
の有用性は理解するのに十分簡単です。 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
最初に思い浮かぶのは、 this :
^(http)([a-z\d]+)$
Pass/Fail Group 1 Group 2 Grouped correctly?
Pass http 123 Yes
Pass http s456 No
Pass http something Yes
それらはすべて合格しますが、グループ2で456
のみが必要だったため、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
がhttps?
の一部であるか[a-z]+|\d+
の一部であるかを決定するとき、結果がいずれかのパスである場合、、正規表現エンジンは常に左側のものを選択します。したがって、グループ2はs
を失います。これは、グループ1が吸い込んだためです。
これを修正するには、 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に入れることを好みます。
?
は、単に前のアイテム(キャラクター、キャラクタークラス、グループ)をオプションにします:
colou?r
「色」と「色」に一致
(swimming )?pool
「プール」と「プール」に一致
??
は同じですが、怠laでもあるため、可能な場合はwillを除外します。それらのドキュメントが述べているように、??実際にはまれです。私はそれを使ったことがない。
他の回答で説明されていることとは別に、正規表現で疑問符を使用する方法はまだ3つあります。
負の先読み
負の先読みは、他の何かが後に続かないものと一致させたい場合に使用されます。負の先読み構造は括弧のペアであり、開始括弧の後に疑問符と感嘆符が続きます。 x(?!x2)
example
There
を考えます現在、デフォルトでは、RegEx e
は、Word e
の3番目の文字There
を見つけます。
_There
^
_
ただし、すぐにe
が続くr
が必要ない場合は、RegEx e(?!r)
を使用できます。結果は次のようになります。
_There
^
_
正の先読み
ポジティブルックアヘッドは同じように機能します。 q(?=u)
は、q
を一致の一部にせずに、直後にu
が続くu
と一致します。ポジティブルックアヘッドコンストラクトは、括弧のペアであり、開き括弧の後に疑問符と等号が続きます。
example
getting
を考えます現在、デフォルトでは、RegEx t
は、Word t
の3番目の文字getting
を見つけます。
_getting
^
_
ただし、すぐにt
が続くi
が必要な場合は、RegEx t(?=i)
を使用できます。結果は次のようになります。
_getting
^
_
非キャプチャグループ
括弧_()
_に正規表現を配置すると、番号付きのキャプチャグループが作成されます。括弧内の正規表現の部分と一致する文字列の部分を保存します。
グループで一致をキャプチャする必要がない場合は、この正規表現を最適化して
_(?:Value)
_