質問

次のコードを取得します。

$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;。

不足しているものは何ですか?

ありがとう。

役に立ちましたか?

解決

理由を見つけたと思います。

  1. 名前付き後方参照はオプションです。
  2. 一致する場合(最初の試行で一致する場合)、正規表現エンジンは<!> quot; LPAREN <!> quot;の左側に立っています。
  3. 正規表現エンジンが次に照合を試みるトークンはスペース文字です。これは、後読み式(?<=LPAREN)が文字列の文字を消費しないためです。
  4. Lがあるため、スペースと一致できません
  5. 正規表現エンジンは、2からのオプションの一致を破棄し、次のスペースが見つかるまで続行します。
  6. すべてのPをキャプチャし、それ以降も一致し、一致を維持します。しかし、これが機能するためには、指定されたグループをあきらめる必要がありました。

後読みが必要な理由がわかりません。どうですか

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top