2016-06-15 3 views
-3

数字の範囲をキャプチャして数値で置き換えますが、特定のタグ内でのみ置換します。PHPでタグ間のテキストを編集するには

$str = "This is some (the numbers are between 8, 9-12) and we have some 9-12 outside"; 

出力は、私は括弧の間である、唯一の9-12をキャプチャする必要がある、とだけではない9-12外括弧それを置き換える

$str = "This is some (the numbers are between 8, 9, 10, 11, 12) and we have some 9-12 outside"; 

でなければなりません。

+1

。インターバル値を抽出して数値のリストに変換し、インターバルを置き換える関数を作成することができます。 –

+0

@JorgeCampos私は最初の部分を処理しましたが、かっこ内の部分文字列への置換をどのように制限するのですか? – Googlebot

+1

'\(。*?([\ d] + - [\ d] +)\)'そして、最初のグループのみを取得する:https://regex101.com/r/lZ1tM5/2 –

答えて

1

あなたはpreg_replace_callback\Gベースのパターンで、このようにそれを行うことができます:あなたは試合を得るために、ステップの数を制限したい場合は、

~ 
(?: # two possible beginnings 
    \G(?!\A) # position after the previous match 
    |   # OR 
    \(  # an opening parenthesis 
) 
[^)0-9]*+ # all that is not a closing parenthesis or a digit 
(?: 
    [0-9]++ (?!-[0-9]) # digits not followed by an hyphen and a digit 
    [^)0-9]* 
)*+ 
\K # the match result starts here 
([0-9]++) # group 1 
- 
([0-9]+) # group 2 
~ 

$str='This is some (the numbers are between 8, 9-12) and we have some 9-12 outside'; 

echo preg_replace_callback('~(?:\G(?!\A)|\()[^)0-9]*+(?:[0-9]++(?!-[0-9])[^)0-9]*)*+\K([0-9]++)-([0-9]+)~', function ($m) { 
    return implode(', ', range($m[1], $m[2])); 
}, $str); 

パターンの詳細パターンの先頭を書き換えることができます:(?:\G(?!\A)|\()このように:\G(?:(?!\A)|[^(]*\()。このようにして、パターンは開始括弧まで失敗することはなくなりますが、パターンの開始時に交互に失敗する(ほとんどの場合)コストを回避して(制限して)迅速に到達します。

+1

これは魔法のように素晴らしいです!私はその無能を信じることができません。もっと良い答えがあるのではないかと私は疑う。 – Googlebot

+1

@All:ありがとうございます。パターンはしばしば改善されます(特に文字列に関する追加情報がある場合)。 '\ G'パターンがどのように設計されているかを知るために時間がかかることをよく理解するためには、どうやって(*連続するかどうか)*いったん終了すると、パターンを改善するためにここにしか存在しない所有量限定子を検索することができます。 –

0

これを試してください:あなたが唯一の正規表現でこれを行うことはできません

preg_match_all('#\([^\)]+\)#', $str, $matches); 
foreach ($matches as $m) { 
    $str = str_replace($m, str_replace('-', ', ', $m), $str); 
} 
関連する問題