2

私はこのような文字列を一致させようとしています:

{{name|arg1|arg2|...|argX}}

正規表現で

で使用preg_matchしています

/{{(\w+)\|(\w+)(?:\|(.+))*}}/

しかし、2つ以上の引数を使用するたびに、このようなものが得られます

Array
(
    [0] => {{name|arg1|arg2|arg3|arg4}}
    [1] => name
    [2] => arg1
    [3] => arg2|arg3|arg4
)

最初の2つのアイテムにはスペースを含めることはできず、残りのアイテムにはスペースを含めることができます。おそらく私はこれにあまりにも長い間取り組んでいますが、エラーを見つけることができません-どんな助けでも大歓迎です。

ありがとう1月

4

5 に答える 5

4

この種の単純なタスクには正規表現を使用しないでください。本当に必要なものは次のとおりです。

$inner = substr($string, 2, -2);
$parts = explode('|', $inner);

# And if you want to make sure the string has opening/closing braces:
$length = strlen($string);
assert($inner[0] === '{');
assert($inner[1] === '{');
assert($inner[$length - 1] === '}');
assert($inner[$length - 2] === '}');
于 2009-08-25T14:19:23.653 に答える
3

問題はここにあります: \|(.+)

デフォルトでは、正規表現は可能な限り多くの文字に一致します。以来 。は任意の文字で、| の他のインスタンスです。これはあなたが望むものではありません。

これを防ぐには、 | を除外する必要があります。式から、「| 以外のすべてに一致する」と言って、\|([^\|]+) になります。

于 2009-08-25T14:46:21.643 に答える
0

もちろん、あなたはこのようなものを得るでしょう:)正規表現には、動的な一致数を返す方法はありません-あなたの場合は引数です。

やりたいことを見ると、現在の正規表現に遅れずについていき、余分な引数を '|' で分解するだけです。それらを args 配列に追加します。

于 2009-08-25T14:49:44.587 に答える
0

1 からNの引数のどこでも機能するはずです

<?php

$pattern = "/^\{\{([a-z]+)(?:\}\}$|(?:\|([a-z]+))(?:\|([a-z ]+))*\}\}$)/i";

$tests = array(
    "{{name}}"                          // should pass
  , "{{name|argOne}}"                   // should pass
  , "{{name|argOne|arg Two}}"           // should pass
  , "{{name|argOne|arg Two|arg Three}}" // should pass
  , "{{na me}}"                         // should fail
  , "{{name|arg One}}"                  // should fail
  , "{{name|arg One|arg Two}}"          // should fail
  , "{{name|argOne|arg Two|arg3}}"      // should fail
  );

foreach ( $tests as $test )
{
  if ( preg_match( $pattern, $test, $matches ) )
  {
    echo $test, ': Matched!<pre>', print_r( $matches, 1 ), '</pre>';
  } else {
    echo $test, ': Did not match =(<br>';
  }
}
于 2009-08-25T14:39:51.983 に答える
0

実際、これは PCRE マニュアルからのものです。

キャプチャ サブパターンが繰り返される場合、キャプチャされる値は、最後の繰り返しに一致した部分文字列です。たとえば、(tweedle[dume]{3}\s*)+ が "tweedledum tweedledee" に一致した後、キャプチャされた部分文字列の値は "tweedledee" になります。ただし、ネストされたキャプチャ サブパターンがある場合は、対応するキャプチャされた値が以前の反復で設定されている可能性があります。たとえば、/(a|(b))+/ が「aba」と一致した後、2 番目にキャプチャされた部分文字列の値は「b」になります。

于 2009-08-25T14:56:51.300 に答える