寻找更好的正则表达式解决方案

时间:2016-09-07 13:03:24

标签: javascript ruby regex

我的意见是:
<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 119blah 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

testinput:
case1 - &gt;两行代码
<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 - &gt;一行代码
<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>

Update2:
这不是dom,它只是我要处理的纯文本。

UPDATE3: 所以关于正则表达式的问题已经解决了,现在我有一个关于比较正则表达式或dom运算之间的速度的问题?怎么可以实施这样的测试?

4 个答案:

答案 0 :(得分: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"]]

答案 1 :(得分:1)

如果它真的不是HTML(嗯?)你可以用

来做
<span question_number="(\d+)">(.*?)<\/span>

See it here at regex101

原始正则表达式的问题在于它是贪心。部分(.*)将匹配尽可能多的字符,确保仍然可以匹配剩余的<\/span>。因此,它找到第一个<span...并匹配最后 </span>。我对解决方案的尝试非贪婪(?中的(.*?)),因此只与第一个</span>匹配。

答案 2 :(得分:1)

即使您坚持认为这不是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。

答案 3 :(得分:0)

我已经看过这个问题,好像有一个字符串涉及 - 而不是DOM环境。在一天结束时,它&lt;&lt;和&gt;这突然使它成为HTML。如果您掌握了该字符串,并了解它将包含哪些字符串及其边界,那么如果问题特定于您的需求,则有许多解决方案。

无论如何,如果您正在寻找答案,并且您知道您的所有问题绝对存在于<span>内且属性为&#34; question_number&#34;然后我想你可以做这样的事情。没有正则表达式。

这是一个简单的版本,演示了如何从HTML字符串中提取信息。为简单起见,我将其粘贴在textarea中,以便您可以看到它实际上正常工作。您可以复制此代码并运行它。

但是,实际上您可能希望获得容器的innerHTML值,您知道该容器包含所有<span>标记。

我知道有许多不同的方法可以解决这个问题,但这可以解决您的具体需求。

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