寻找更好的正则表达式解决方案[重复]

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> 注意:它们在不同的行 输出为:18blah blah blah 119,blah blah blah 2

但是当输入是<span question_number="18"> blah blah blah 1</span><span question_number="19"> blah blah blah 2</span> 在同一行

我的输出是18blah 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.

您原来的正则表达式的问题在于它是贪婪(.*) 部分将匹配尽可能多的字符,确保剩余的 &lt;\/span&gt; 仍然可以匹配。所以它会找到第一个 &lt;span... 并匹配到 last &lt;/span&gt;。我对解决方案的尝试是非贪婪的((.*?) 中的 ?),因此只匹配第一个 &lt;/span&gt;

【讨论】:

【参考方案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 的东西。

【讨论】:

以上是关于寻找更好的正则表达式解决方案[重复]的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式在字符串中有一个字母[重复]

PHP正则表达式匹配所有网址[重复]

如何使用正则表达式避免在 unicode 重音后大写字母 [重复]

在 HTML 单元格中使用 HTML 解析 Python 正则表达式 [重复]

Java - 正则表达式拆分输入文本但保留分隔符[重复]

正则表达式不包含某些单词[重复]