我正在尝试用标签包装以“##”开头的每一行。尝试为文本格式化实现类似GitHub / Stackoverflow的语法。
这就是我得到的:
$value = preg_replace('/^## (.*)$/m', '<p>$1</p>', $value);
谷歌搜索了一段时间后,这似乎是正确的解决方案,但它没有按预期工作或我只是不明白的东西......
示例文字:
## Some header 1
Some text that doesn't need to be altered
## Some header 2
这就是结果:
<p>Some header 1
</p>
Some text that doesn't need to be altered
<p>Some header 2</p>
如您所见,第二个标题处理正常,因为它位于文本的末尾。但是,第一个标题在结束标记之前的末尾会得到一个额外的新行。我该如何摆脱它?
答案 0 :(得分:2)
似乎在您当前的PCRE设置中,一个点匹配LF以外的所有字符(\n
,换行符),因此它匹配CR(\r
,回车),并且也是一个换行符。
PCRE支持覆盖默认换行符(以及$
锚点的行为)。要使.
匹配除CR和LF之外的所有字符,请启用相应的标志:
'/(*ANYCRLF)^## (.*)$/m'
^^^^^^^^^^
$
将在\r\n
之前断言行尾。
在rexegg.com处详细了解此动词和其他动词:
默认情况下,当编译PCRE时,你会告诉它在遇到
.
时要考虑换行(除非在dotall mode中,否则它与换行符不匹配),以及multiline mode中的^
和$
锚点行为。您可以使用以下修饰符覆盖此默认值:✽
(*CR)
只有回车才被视为换行符 ✽(*LF)
只有换行符被视为换行符(如在Unix上) ✽(*CRLF)
只有回车符后跟换行符才被视为换行符(如Windows) ✽(*ANYCRLF)
以上三种中的任何一种都被认为是换行符 ✽(*ANY)
任何Unicode换行序列都被视为换行符例如,
(*CR)\w+.\w+
匹配Line1\nLine2
,因为该点可以匹配\n
,这不被认为是换行符。见demo。