2012-03-09 6 views
0

私は理解できないような単純な十分な正規表現の問題を抱えています。Regex/Preg_replace、検索のポイントを変更

これは私がで始まる式である:これは私がして終了したいものです

## a ## 
text1 
## b ## 
text2 
## C## 
text3 

<text title="a"> 
text1 
</text> 

<text title="b"> 
text2 
</text> 

<text title="c"> 
text3 
</text> 

これまでのところ、これは私が試したものです:

preg_replace ('/##(.*?)##(.*?)##/s', '<text title="$1">$2</text>==', $data); 

私が抱えている問題は、preg_replaceが最後の試合の最後から検索を再開し、変更する方法があることですこの?

また、私の戦略がひどい場合、これを行うにはどうすればよいでしょうか?

答えて

1

あなたの問題は、式の中の最後の##が最初の一致で消費されるため、次の一致と一致しないことです。

これを避けるために先読みを使用できます。これと同じように:

/##(.*?)##(.*?)(?=##)/s 

しかし、あなたはおそらくもっと何かしたい:Qtaxが指摘したように

/^## *([^#]+?) *##$(.*?)(?=^##[^#]+##$|\z)/ms 
+0

ありがとうございます!私はこれをうまく使いこなすことができました。アランムーアが指摘した最後の試合の特別なケースに対処するために余分なラインを追加するだけでした。 – ThreepwoodG

0

を、各試合は、次の試合だったはずです何から##を消費します。先読みに切り替えると役立ちますが、最後の試合の特別なケースを処理する必要があります。しかし、私はあなたがさらにを見て、次の行でを見て、それほど消費しないと思う。これをチェックアウト:

$result = preg_replace('/^## *(.*?) *##\s+(.*)/m', 
         "<text title='$1'>\n$2\n</text>\n", 
         $subject); 

はここdemoです。

最も重要な変更は、s修飾子を削除することでした。改行にマッチするためにドットが必要な場所は1つしかなく、それに合わせて\s+を使用しています。 s修飾子がなければ、安全に(.*)を使用して2行目を消費することができます。そしてボーナスとして、私は(.*?)が最初の行の閉じ込めをエスケープできないことを知っています(入力が不正な場合にのみ発生します)。

関連する問題