2016-09-07 125 views
-4

我输入的是:
<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>
通知:他们在不同的林ES
输出为: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:
情形1 - >的两行代码
<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 - 的代码>一行
<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操作之间的速度问题?怎么可能实施这样的测试?

+9

为什么你用正则表达式匹配HTML? http://stackoverflow.com/questions/590747/using-regular-expressions-to-parse-html-why-not – epascarello

+6

我催促你阅读http://stackoverflow.com/questions/1732348/regex-match-open -tags-except-xhtml-self-contained-tags/1732454#1732454之前为时已晚 –

+0

请问有人可以编辑这个吗? – evolutionxbox

回答

1

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

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

See it here at regex101做到这一点。

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

+0

非常感谢你 – MohanL

0

我已经看过这个问题,就好像有一个字符串涉及 - 而不是一个DOM环境。在一天结束时,它是<和>,突然使它成为HTML。如果你掌握了这个字符串,并且你明白它将包含什么以及它的边界,那么如果问题是针对你的需求的话,那么就有许多问题的解决方案。

无论如何,如果你正在寻找一个答案,你知道你所有的问题绝对生活在一个<span>与属性“question_number”,那么我想你可以做这样的事情。没有正则表达式。

这是一个简单的版本,演示如何从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> 
+0

注意:在你发布你的答案(大概是在你写它的时候)之前,OP删除了[tag:javascript]标签并且添加了[tag:ruby]标签约10分钟。不幸的是,这使你的答案无效。 –

+0

嗨,谢谢你的工作,所以我知道如何做dom操作,但是你知道要测试使用正则表达式和dom操作之间的速度吗? – MohanL

+0

我不知道你正在解析的特定代码的正则表达式和dom操作之间的速度差异。我也不知道你打算进行多少次手术。对不起,我不能有任何进一步的帮助。 @JörgWMittag - 谢谢你的头!是的,这正是发生了什么! grrr :) –

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"]] 
+0

非常感谢。这太棒了。 – MohanL

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解析器是不是很清楚,我。