我有一个看似简单的正则表达式问题,我似乎无法弄清楚!
这是我开头的表达式:
## 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从最后一场比赛结束时重新开始搜索,有没有办法改变这个?
或者,如果我的策略很糟糕,那么最好的方法是什么?
答案 0 :(得分:1)
您的问题是第一个匹配消耗了表达式中的最后一个##
,因此它与下一个匹配项不匹配。
您可以使用前瞻来避免这种情况。像这样:
/##(.*?)##(.*?)(?=##)/s
但你可能想要更像的东西:
/^## *([^#]+?) *##$(.*?)(?=^##[^#]+##$|\z)/ms
答案 1 :(得分:0)
正如Qtax指出的那样,每场比赛都会消耗##
本来应该是下一场比赛。切换到前瞻有帮助,但你仍然需要处理最后一场比赛的特殊情况。但我认为你甚至不需要在下一行看,更不用说消耗它了。看看这个:
$result = preg_replace('/^## *(.*?) *##\s+(.*)/m',
"<text title='$1'>\n$2\n</text>\n",
$subject);
这是 demo 。
我做的最重要的改变是放弃s
修饰符。只有一个地方需要一个点来匹配换行符,我使用\s+
来匹配它。如果没有s
修饰符,我可以安全地使用(.*)
来使用第二行。作为奖励,我知道(.*?)
无法逃脱第一行的限制(只有在输入格式错误时才会发生)。