1

次の入力テキストを PHP の正規表現と照合/置換しようとしています。

{#var1>var2}
  {#>empty}inside empty{#>empty}
  before rows
  {#>firstrow}inside firstrow{#>firstrow}
  {#>row}inside row{#>row}
  {#>lastrow}inside lastrow{#>lastrow}
  after rows
{#}

ここで、var1>var2 は配列です。

$var1['var2'] = array('key1' => 'value1', 'key2' => 'value2', ...)

正規表現 (preg_replace_callback を使用) でテキストを解析する次のクラスがあります。

class parse {

  public static function text($text) {
    $text = preg_replace_callback('/\{(#+)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)((?:\>[a-zA-Z0-9_\x7f-\xff]*)*)\}\s*(\{\1\>empty\}\s*(.*?)\s*\{\1\>empty\})?\s*(.*?)\s*(\{\1\>firstrow\}\s*(.*?)\s*\{\1\>firstrow\})?\s*(\{\1\>row\}\s*(.*?)\s*\{\1\>row\})?\s*(\{\1\>lastrow\}\s*(.*?)\s*\{\1\>lastrow\})?\s*(.*?)\s*\{\1\}/s', array('parse', 'replace_array'), $text);
    return $text;
  }

  public static function replace_array($matches) {
    print_r($matches);
  }
}

私は(間違った)出力を取得します:

Array (
  [0] => {#var1>var2>var3} {#>empty}inside empty{#>empty} before rows {#>firstrow}inside firstrow{#>firstrow} {#>row}inside row{#>row} {#>lastrow}inside lastrow{#>lastrow} after rows {#}
  [1] => #
  [2] => var1
  [3] => >var2
  [4] => {#>empty}inside empty{#>empty}
  [5] => inside empty
  [6] =>
  [7] =>
  [8] =>
  [9] =>
  [10] =>
  [11] =>
  [12] =>
  [13] => before rows {#>firstrow}inside firstrow{#>firstrow} {#>row}inside row{#>row} {#>lastrow}inside lastrow{#>lastrow} after rows
) 

入力テキストから「前の行」を削除すると、正しい結果が得られます。

Array (
  [0] => {#var1>var2>var3} {#>empty}inside empty{#>empty} {#>firstrow}inside firstrow{#>firstrow} {#>row}inside row{#>row} {#>lastrow}inside lastrow{#>lastrow} after rows {#}
  [1] => #
  [2] => var1
  [3] => >var2
  [4] => {#>empty}inside empty{#>empty}
  [5] => inside empty
  [6] =>
  [7] => {#>firstrow}inside firstrow{#>firstrow}
  [8] => inside firstrow
  [9] => {#>row}inside row{#>row}
  [10] => inside row
  [11] => {#>lastrow}inside lastrow{#>lastrow}
  [12] => inside lastrow [13] => after rows
)

私はすでに日を探しています。これは少しばかげた問題になると思いますが、見つけることができません...何か助けはありますか?

4

1 に答える 1

0

これは私のために働く:

\{(#+)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)((?:\>[a-zA-Z0-9_\x7f-\xff]*)*)\}\s*(\{\1\>empty\}\s*(.*?)\s*\{\1\>empty\})?\s*([^\n]*)\s*(\{\1\>firstrow\}\s*(.*?)\s*\{\1\>firstrow\})?\s*(\{\1\>row\}\s*(.*?)\s*\{\1\>row\})?\s*(\{\1\>lastrow\}\s*(.*?)\s*\{\1\>lastrow\})?\s*(.*?)\s*\{\1\}

私が知る限り(そして、それを伝えるのは本当に難しいです)、問題はこの部分でした

{\1\>empty\})?\s*(.*?)\s*

具体的には、フラグを使用しているため、(.*?) 一致しません。貪欲ではないため、最初の一致 (この場合は改行) で停止します。before rows\s.

私がしたことは、それを次のように置き換えることでした:

 {\1\>empty\})?\s*([^\n]*)\s*

ここではドット演算子を実際に使用できないため、基本的に改行以外のすべてを提供するように指示します。

私の推論が 100% 正しいかどうかはわかりませんが、私のパターンはここでわかるように機能するはずです。

http://regex101.com/r/dS4fG9

于 2014-01-09T10:49:40.343 に答える