寻找更好的正则表达式解决方案[重复]
Posted
技术标签:
【中文标题】寻找更好的正则表达式解决方案[重复]【英文标题】:looking for a better regex solution [duplicate] 【发布时间】:2017-01-15 04:36:18 【问题描述】:我的输入是:<span question_number="18"> blah blah blah 1</span><span question_number="19"> blah blah blah 2</span>
我希望我的正则表达式匹配这个
<span question_number="somenumber">xxxx</span>
模式
并且期望的输出是 1.somenumber 2.xxxx
我写了一个简单的解决方案,可以覆盖 <span question_number="18"> blah blah blah 1</span>
<span question_number="19"> blah blah blah 2</span>
注意:它们在不同的行
输出为:18
、blah blah blah 1
和 19
,blah blah blah 2
但是当输入是<span question_number="18"> blah blah blah 1</span><span question_number="19"> blah blah blah 2</span>
在同一行
我的输出是18
,blah blah blah 1</span><span question_number="19"> blah blah blah 2
我怎样才能绕过这个问题?
更新:
正则表达式:/\<span question_number=(?:\")*(\d*)(?:\")*>(.*)<\/span>/ig
测试输入:
case1 -> 两行代码 <span question_number="54">often graces doorways tied into ropes called</span>
<span question_number="54">often graces doorways tied into ropes called <i>ristras</i>.</span>
case2 -> 一行代码<span question_number="54">often graces doorways tied into ropes called</span><span question_number="54">often graces doorways tied into ropes called <i>ristras</i>.</span>
更新2: 这不是 dom ,它只是我要处理的纯文本。
更新3: 所以我关于正则表达式的问题解决了,现在我有一个关于比较正则表达式或 dom 操作之间的处理速度的问题?怎么可能实施这样的测试?
【问题讨论】:
为什么要用正则表达式匹配 html? ***.com/questions/590747/… 我敦促您在为时已晚之前阅读***.com/questions/1732348/… 请,请:不要使用正则表达式来解析 HTML! (见***.com/a/1732454/709439 :-) 改变你的问题以使其他人的努力无效是不礼貌的。在这种特殊情况下,当您突然改变主意并现在想要一个 Ruby 解决方案时,很多人已经投入了大量工作来解决您的 javascript 问题。单独问一个关于 Ruby 的问题会更有礼貌,而不是把人们已经投入到你的 JavaScript 问题中的所有辛苦工作都扔掉。 请不要在您的问题(或答案)中使用“编辑”或“更新”标签,因为这会导致难以阅读的文本。相反,将更改合并到文本中,就好像它们最初在那里一样。如果需要,我们可以看到发生了什么变化。另外,请阅读格式帮助,这有助于我们了解您的要求。我们越容易阅读,就越能快速准确地为您提供帮助。 【参考方案1】:我已经把这个问题看作是涉及到一个字符串——而不是一个 DOM 环境。归根结底,是 突然变成了 HTML。如果您可以控制该字符串并且您了解它将包含什么以及它的边界,那么如果它是针对您的需求的,那么就有很多解决方案。
无论如何,如果您正在寻找答案并且您知道您的所有问题都绝对存在于<span>
中,并且属性为“question_number”,那么我想您可以这样做。没有正则表达式。
这是一个简单的版本,演示了如何从 HTML 字符串中提取信息。为简单起见,我将其粘贴在 textarea 中,以便您可以看到它实际工作。您可以复制此代码并运行它。
但是,实际上,您可能希望获取包含所有 <span>
标记的容器的 innerHTML 值。
我知道有很多不同的方法可以解决这个问题,但这是对您特定需求的回答。
<html><body>
<textarea id='htmlstring'>
<div>Random HTML Before</div>
<span question_number="18">blah blah blah 1</span>
<span question_number="19">blah blah blah 1</span>
<span question_number="21">blah blah blah 1</span>
<span question_number="22">blah blah blah 1</span>
<div>Random HTML After</div>
</textarea>
<script type="text/javascript">
var t = document.getElementById('htmlstring');
var q = t.value.split("<span question_number=");
q.shift();
for(var i in q)
var d = q[i].split("</span>")[0];
d = d.replace("\">","|");
d = d.replace("\"","");
d = d.split("|");
alert("num="+d[0]+" val="+d[1]);
</script>
</body></html>
【讨论】:
注意:OP 删除了 javascript 标签并在您发布答案前大约 10 分钟添加了 ruby 标签(所以大概是在您写它的时候)。不幸的是,这会使您的答案无效。 您好,谢谢您的工作,所以我了解如何进行 dom 操作,但是您知道测试使用 regex 和 dom 操作之间的速度吗? 我不知道你正在解析的具体代码上正则表达式和dom操作的速度差异。我也不知道您打算执行多少次操作。抱歉,我无法提供任何进一步的帮助。 @JörgWMittag - 感谢您的提醒!是的,这正是发生的事情! grrr :)【参考方案2】:如果它真的不是 HTML(嗯?)你可以用它来做
<span question_number="(\d+)">(.*?)<\/span>
See it here at regex101.
您原来的正则表达式的问题在于它是贪婪。 (.*)
部分将匹配尽可能多的字符,确保剩余的 <\/span>
仍然可以匹配。所以它会找到第一个 <span...
并匹配到 last </span>
。我对解决方案的尝试是非贪婪的((.*?)
中的 ?
),因此只匹配第一个 </span>
。
【讨论】:
【参考方案3】:虽然您没有解析整个 HTML 文档,但您的输入显然包含 HTML 元素。
无论哪种情况,Nokogiri 都是首选库:
require 'nokogiri'
input = '<span question_number="18"> blah blah blah 1</span><span question_number="19"> blah blah blah 2</span>'
doc = Nokogiri::HTML.fragment(input)
doc.css('span').map |s| [s[:question_number], s.text]
#=> [["18", " blah blah blah 1"], ["19", " blah blah blah 2"]]
【讨论】:
【参考方案4】:即使你坚持认为这不是 HTML,但它看起来和闻起来确实像它,事实上,它可以很容易地被 HTML 解析器解析:
require 'nokogiri'
doc = Nokogiri::HTML.fragment <<~'HTML'
<span question_number="54">often graces doorways tied into ropes called</span>
<span question_number="54">often graces doorways tied into ropes called <i>ristras</i>.</span>
HTML
doc.xpath('span').map |span| next span[:question_number].to_i, span.text
#=> [[54, "often graces doorways tied into ropes called"], [54, "often graces doorways tied into ropes called ristras."]]
我不太清楚你为什么坚持不使用 HTML 解析器来处理 明显 HTML 的东西。
【讨论】:
以上是关于寻找更好的正则表达式解决方案[重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用正则表达式避免在 unicode 重音后大写字母 [重复]