我正在制作一个简单的 Textile 解析器,并正在尝试为“blockquote”编写一个正则表达式,但在匹配多个新行时遇到了困难。例子:
bq。第一行报价 第二行报价 第三行报价 不是报价的一部分
它将被替换为块引用标签,preg_replace()
因此基本上它需要匹配"bq."
它遇到的第一个双新行之间的所有内容。我能做到的最好的就是得到报价的第一行。谢谢
试试这个正则表达式:
(?s)bq\.((?!(\r?\n){2}).)*+
意义:
(?s) # enable dot-all option
b # match the character 'b'
q # match the character 'q'
\. # match the character '.'
( # start capture group 1
(?! # start negative look ahead
( # start capture group 2
\r? # match the character '\r' and match it once or none at all
\n # match the character '\n'
){2} # end capture group 2 and repeat it exactly 2 times
) # end negative look ahead
. # match any character
)*+ # end capture group 1 and repeat it zero or more times, possessively
匹配 Windows、*nix 和(更新的\r?\n
)MacOS 换行符。如果您需要考虑真正的旧 Mac 计算机,请将单曲添加\r
到其中:\r?\n|\r
这个接受的答案只为我捕获了该块的最后一个字符。我最终使用了这个:
$text =~ /(?s)bq\.(.+?)\n\n/g
这行得通吗?
'/(.+)\n\n/s'
我相信's'代表单行。
我的直觉告诉我……
preg_match("/^bq\. (.+?)\n\n/s", $input, $matches)
就像上面的家伙说的那样,正则表达式末尾的s
标志意味着将匹配换行符。通常,没有这个,RegExs 是一种单行的东西。/
.
?
然后后面的问号.+
表示非贪婪匹配,因此.+
不会尽可能匹配;相反,它将匹配可能的最小值,以便\n\n
匹配第一个可用的双线。
您计划在多大程度上支持 Textile 的功能?因为您的 RegEx 可能会变得非常复杂,因为 Textile 允许...
bq.. This is a block quote
This is still a block quote
或者...
bq(funky). This is a block quote belonging to the class funky!
bq{color:red;}. Block quote with red text!
我认为,所有这些你的正则表达式替换技术都无法处理。
编辑:呃,误读了这个问题..“bq”。意义重大。
echo preg_replace('/^bq\.(.+?)\n\n/s', '<blockquote>$1</blockquote>', $str, 1);
有时通过 webforms 输入的数据包含 \r\n 而不仅仅是 \n 这将使它
echo preg_replace('/^bq\.(.+?)\r\n\r\n/s', '<blockquote>$1</blockquote>', $str, 1);
问号使它在找到第一个双重返回之后添加结束块引号(我相信它被称为“非贪婪”),所以任何其他双重返回都被单独留下(如果这不是你想要的,显然把它拿出来)。