疑似コードでの正規表現の知識は十分にありますが、php regex perl でやりたいことを翻訳するのに苦労しています。
preg_match を使用して式の一部を抽出しようとしています。
次の文字列が${classA.methodA.methodB(classB.methodC(classB.methodD)))}
あり、2 つのことを行う必要があります。
を。構文を検証する
${classA.methodA.methodB(classB.methodC(classB.methodD)))}
有効${classA.methodA.methodB}
有効${classA.methodA.methodB()}
有効ではありません${methodB(methodC(classB.methodD)))}
有効ではありません
b. ${classA.methodA.methodB(classB.methodC(classB.methodD)))}
返される情報を抽出する必要があります
1. classA
2. methodA
3. methodB(classB.methodC(classB.methodD)))
このコードを作成しました
$expression = '${myvalue.fdsfs.fsdf.blo(fsdf.fsfds(fsfs.fs))}';
$pattern = '/\$\{(?:([a-zA-Z0-9]+)\.)(?:([a-zA-Z\d]+)\.)*([a-zA-Z\d.()]+)\}/';
if(preg_match($pattern, $expression, $matches))
{
echo 'found'.'<br/>';
for($i = 0; $i < count($matches); $i++)
echo $i." ".$matches[$i].'<br/>';
}
結果は次のとおりです。
見つかった
0 ${myvalue.fdsfs.fsdf.blo(fsdf.fsfds(fsfs.fs))}
1 myvalue
2 fsdf
3 blo(fsdf.fsfds(fsfs.fs))
明らかに、反復的なメソッドを抽出するのが難しく、適切に検証されていません (正直なところ、他の問題を解決したら最後に残しました)。そのため、空の括弧が許可され、括弧が開かれたかどうかを確認していません。閉じなければなりません。
皆さんありがとう
アップデート
X m.buettner
ご協力いただきありがとうございます。私はあなたのコードをすばやく試しましたが、バイパスすることはできますが、非常に小さな問題が発生します。この問題は、ここに投稿しなかった以前のコードの 1 つと同じです。これは、この文字列を試したときです。
$expression = '${myvalue.fdsfs}';
パターン定義を使用すると、次のように表示されます。
found
0 ${myvalue.fdsfs}
1 myvalue.fdsfs
2 myvalue
3
4 fdsfs
ご覧のとおり、3 行目は存在しない空白として捉えられています。なぜそうしていたのか理解できなかったので、方法を教えてもらえますか、それともPHPの正規表現の制限のためにそれと一緒に暮らす必要がありますか?
とは言え、ありがとうとしか言いようがありません。あなたは私の問題に答えただけでなく、パターンを開発する際に従うべき適切な道筋について多くの提案をして、できるだけ多くの情報を入力しようとしました.
最後に、私が(愚かな)1つの小さな重要なケースを追加するのを忘れていました。これは、複数のパラメーターをコンマで割ったものです。
$expression = '${classA.methodAA(classB.methodBA(classC.methodCA),classC.methodCB)}';
$expression = '${classA.methodAA(classB.methodBA(classC.methodCA),classC.methodCB,classD.mehtodDA)}';
有効である必要があります。
私はこれに編集しました
$expressionPattern =
'/
^ # beginning of the string
[$][{] # literal ${
( # group 1, used for recursion
( # group 2 (class name)
[a-z\d]+ # one or more alphanumeric characters
) # end of group 2 (class name)
[.] # literal .
( # group 3 (all intermediate method names)
(?: # non-capturing group that matches a single method name
[a-z\d]+ # one or more alphanumeric characters
[.] # literal .
)* # end of method name, repeat 0 or more times
) # end of group 3 (intermediate method names);
( # group 4 (final method name and arguments)
[a-z\d]+ # one or or more alphanumeric characters
(?: # non-capturing group for arguments
[(] # literal (
(?1) # recursively apply the pattern inside group 1
(?: # non-capturing group for multiple arguments
[,] # literal ,
(?1) # recursively apply the pattern inside group 1 on parameters
)* # end of multiple arguments group; repeat 0 or more times
[)] # literal )
)? # end of argument-group; make optional
) # end of group 4 (method name and arguments)
) # end of group 1 (recursion group)
[}] # literal }
$ # end of the string
/ix';
X カジミール エ ヒッポリュテ
あなたの提案も良いですが、このコードを使用するときは少し複雑な状況を暗示しています。コード自体は簡単に理解できますが、柔軟性が低下します。そうは言っても、将来必ず役立つ多くの情報を私に与えてくれました.
X デノマレス
サポートしていただきありがとうございますが、これを試すとコードが落ちます:
$sourcestring='${classA1.methodA0.methodA1.methodB1(classB.methodC(classB.methodD))}';
結果は次のとおりです。
Array
( [0] => 配列 ( [0] => ${classA1.methodA0.methodA1.methodB1(classB.methodC(classB.methodD))} )
[1] => Array
(
[0] => classA1
)
[2] => Array
(
[0] => methodA0
)
[3] => Array
(
[0] => methodA1.methodB1(classB.methodC(classB.methodD))
)
)
そのはず
[2] => Array
(
[0] => methodA0.methodA1
)
[3] => Array
(
[0] => methodB1(classB.methodC(classB.methodD))
)
)
また
[2] => Array
(
[0] => methodA0
)
[3] => Array
(
[0] => methodA1
)
[4] => Array
(
[0] => methodB1(classB.methodC(classB.methodD))
)
)