Ruby使用正则表达式进行分割 - 正则表达式不按照我的意愿工作

3

i have this string

string = "<p>para1</p><p>para2</p><p>para3</p>"

我希望在para2文本处进行分割,以便我得到这个结果。
["<p>para1</p>", "<p>para3</p>"]

问题在于,有时para2可能没有被包含在p标签中(并且p标签外部和内部可能存在可选空格)。我认为以下代码可以解决这个问题:

string.split(/\s*(<p>)?\s*para2\s*(<\/p>)?\s*/)

但是,我得到了这个:
["<p>para1</p>", "<p>", "</p>", "<p>para3</p>"]

它没有将起始和结束的p标签拉入匹配模式中 - 它们应该作为分割的一部分被消除。 Ruby的正则表达式默认是贪婪的,所以我认为它们会被拉进来。如果我使用gsub而不是split,则似乎得到了确认:

string.gsub(/\s*(<p>)?\s*para2\s*(<\/p>)?\s*/, "XXX")
=> "<p>para1</p>XXX<p>para3</p>"

这些东西在这里被拉进来并且被清除掉了,但是在分裂上没有。有任何想法吗?

谢谢,马克斯


2
记住,你永远不能真正使用正则表达式解析HTML。如果这个字符串在任何方面依赖于外部输入,请使用像hpricot或nokogiri这样的HTML解析器。 - Matchu
1个回答

8

将捕获组(…)替换为非捕获组(?:…)

/\s*(?:<p>)?\s*para2\s*(?:<\/p>)?\s*/

1
这个答案是正确的。当你使用带有捕获组的正则表达式进行分割时,它会将捕获结果放入数组中,因此你可以执行更复杂的扫描/分割操作。 - mckeed
神奇...我不知道 Ruby 中有这个! - btelles
谢谢Gumbo,这就解决了问题。我以前从未听说过非捕获组,这是一个非常有用的知识点。 - Max Williams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接