予測
一致はシーケンスとして定義されます。
"
入力文字列の最初から開始します。"
これを1番目またはオープニングと呼びましょう"
。
;
開店前はありません"
;
シーケンスの最後"
が奇数の場合、最初から数えて、シーケンスで許可され"
ます。
;
シーケンスの最後"
が偶数の場合、最初から数えて、シーケンスで許可されません"
。
"
上記の条件を満たす最も遠いところで終了します。
解決
この正規表現(生の形式)との最初の一致を見つけます。
^(?> [^; "] *)"((?>(?> "[^";] *(?= "[^"] * $)| "[^";] * "| [^" ] *)+)) "
C#文字列リテラルの場合:
"^(?>[^;\"]*)\"((?>(?>\"[^\";]*(?=\"[^\"]*$)|\"[^\";]*\"|[^\"]*)+))\""
結果は最初のキャプチャグループになります。
説明
構文の説明:
(?>pattern)
非バックトラッキング/所有格の部分式です。エンジンがバックトラックするのを防ぎます。これは最適化の一形態です。
(?=pattern)
ゼロ幅の正の先読みです。前方の文字列pattern
がテキストを消費せずにに準拠していることを確認します。
|
交替です。ここで注意したいのは、正規表現指向エンジンは各ルールを左から右にチェックし、一致するものが見つかった場合は他のルールを考慮しないということです。つまり、一致を決定する際には順序が重要です。
- それらは非常に基本的なものなので、あなたは残りの部分に精通していると思います。
説明のために、非バックトラッキング最適化を削除した生の正規表現を使用します。
^ [^; "] *"((?: "[^";] *(?= "[^"] * $)| "[^";] * "| [^"] *)+) "
「1行の最初と最後の引用」の要件により、1行あたり最大1つの一致があります。
要件を分析することにより、関心のある部分の前;
のテキストに(要件の一部)または"
(そうでない場合は引用符が最初になりません)を含めるべきではないことがわかります。したがって、^[^;"]*
文字列の先頭から一致を固定し、最初の引用符まですべてを一致させるように記述できます"
。
これは引用符で囲まれた文字列部分であり、説明を簡単にするために分割されています。
「」
((
(?:
"[^";] *(?= "[^"] * $)
|
"[^";] * "
|
[^ "] *
)+
)。
「」
これらの3つのフラグメントに焦点を当てて、ボトムアップから説明を始めましょう。
"[^";] *(?= "[^"] * $)
"[^";] * "
[^ "] *
ここでのすべての場合において、最後に遭遇した引用は常に奇数の引用です。
[^"]*
;
:最後の引用符は奇数引用符であることが保証されているため、。を除くすべてを含めることができます"
。
"[^";]*"
:最後の引用符は奇数引用符であり、この後も奇数引用符です。この部分は、引用符が偶数の後に;
許可されていない部分を扱います。
"[^";]*(?="[^"]*$)
:これは、文字列の引用符の数が奇数(> = 3)の場合を扱うトリッキーな部分です。偶数引用符の後に、文字列;
の最後の引用符がないことを確認し"
ました。「文字列の最後の引用符が続く"
」は、先読みで実現されます(?="[^"]*$)
。
非バックトラッキング最適化を適用できるように、バックトラックを回避するためにフラグメント"[^";]*(?="[^"]*$)
を前に配置する必要があります。"[^";]*"