4

我正在制作一个简单的 Textile 解析器,并正在尝试为“blockquote”编写一个正则表达式,但在匹配多个新行时遇到了困难。例子:

bq。第一行报价
第二行报价
第三行报价

不是报价的一部分

它将被替换为块引用标签,preg_replace()因此基本上它需要匹配"bq."它遇到的第一个双新行之间的所有内容。我能做到的最好的就是得到报价的第一行。谢谢

4

5 回答 5

6

试试这个正则表达式:

(?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

于 2010-02-08T14:47:42.837 回答
1

这个接受的答案只为我捕获了该块的最后一个字符。我最终使用了这个:

$text =~ /(?s)bq\.(.+?)\n\n/g
于 2015-11-11T23:18:57.497 回答
0

这行得通吗?

'/(.+)\n\n/s'

我相信's'代表单行。

于 2010-02-08T14:35:33.077 回答
0

我的直觉告诉我……

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!

我认为,所有这些你的正则表达式替换技术都无法处理。

于 2010-02-08T14:43:45.497 回答
0

编辑:呃,误读了这个问题..“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);

问号使它在找到第一个双重返回之后添加结束块引号(我相信它被称为“非贪婪”),所以任何其他双重返回都被单独留下(如果这不是你想要的,显然把它拿出来)。

于 2010-02-08T14:44:33.763 回答