【问题标题】: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? stackoverflow.com/questions/590747/…
  • 我敦促您在为时已晚之前阅读stackoverflow.com/questions/1732348/…
  • 请,请:不要使用正则表达式来解析 HTML! (见stackoverflow.com/a/1732454/709439 :-)
  • 改变你的问题以使其他人的努力无效是不礼貌的。在这种特殊情况下,当您突然改变主意并现在想要一个 Ruby 解决方案时,很多人已经投入了大量工作来解决您的 JavaScript 问题。单独问一个关于 Ruby 的问题会更有礼貌,而不是把人们已经投入到你的 JavaScript 问题中的所有辛苦工作都扔掉。
  • 请不要在您的问题(或答案)中使用“编辑”或“更新”标签,因为这会导致难以阅读的文本。相反,将更改合并到文本中,就好像它们最初在那里一样。如果需要,我们可以看到发生了什么变化。另外,请阅读格式帮助,这有助于我们了解您的要求。我们越容易阅读,就越能快速准确地为您提供帮助。

标签: javascript ruby regex


【解决方案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 的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-25
        • 2014-07-20
        • 1970-01-01
        • 1970-01-01
        • 2018-11-21
        • 1970-01-01
        • 2013-01-09
        • 2010-10-25
        相关资源
        最近更新 更多