質問
次のコードを取得します。
$target = 'NAME FUNC LPAREN P COMMA P COMMA P RPAREN';
//$target = 'NAME FUNC LPAREN P RPAREN';
//$target = 'NAME FUNC LPAREN RPAREN';
$pattern = '/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:(?<=LPAREN)(?: (?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA)))/';
preg_match_all($pattern,$target,$matches,PREG_OFFSET_CAPTURE|PREG_PATTERN_ORDER);
NAME、FUNC、および$ target内の各Pの位置を取得する必要があります(したがってPREG_OFFSET_CAPTURE)。このパターンはPsで機能しますが、名前付きグループ<!> quot; ruleName <!> quot;のいずれにも一致しません。または<!> quot; funcName <!> quot;。
不足しているものは何ですか?
ありがとう。
解決
理由を見つけたと思います。
- 名前付き後方参照はオプションです。
- 一致する場合(最初の試行で一致する場合)、正規表現エンジンは<!> quot; LPAREN <!> quot;の左側に立っています。
- 正規表現エンジンが次に照合を試みるトークンはスペース文字です。これは、後読み式
(?<=LPAREN)
が文字列の文字を消費しないためです。 - Lがあるため、スペースと一致できません
- 正規表現エンジンは、2からのオプションの一致を破棄し、次のスペースが見つかるまで続行します。
- すべての
P
をキャプチャし、それ以降も一致し、一致を維持します。しかし、これが機能するためには、指定されたグループをあきらめる必要がありました。
後読みが必要な理由がわかりません。どうですか
/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
所属していません StackOverflow