ruby – 如何在不知道名称的情况下使用正则表达式为其内容获取XM
发布时间:2020-12-17 01:27:59 所属栏目:百科 来源:网络整理
导读:我简化时看起来像这样的 XML: node_set = Nokogiri::XML('PARENT SOME_TAG12:12:1222/SOME_TAG HOLY_TAG12:12:1222/HOLY_TAG MAJOR_TAG12:12:1222/MAJOR_TAG FOO_FOO12:12:1222/FOO_FOO/PARENT') 我所知道的只是如何为此写一个正则表达式: (d+):(d+):(d
我简化时看起来像这样的
XML:
node_set = Nokogiri::XML(' <PARENT> <SOME_TAG>12:12:1222</SOME_TAG> <HOLY_TAG>12:12:1222</HOLY_TAG> <MAJOR_TAG>12:12:1222</MAJOR_TAG> <FOO_FOO>12:12:1222</FOO_FOO> </PARENT>' ) 我所知道的只是如何为此写一个正则表达式: (d+):(d+):(d+) 我在官方网站上阅读了一些关于正则表达式匹配的文章,但没有答案如何做到这一点.只有如何将用户函数调用到xpath方法的机制. 如果不通过regexp知道它的名字,我怎么能得到所有这些标签? 解决方法
Nokogiri不支持XPath 2.0
matches 功能,因此您需要使用Ruby来执行正则表达式:
hits = node_set.xpath("//text()").grep(/d+:d+:d+/).map(&:parent) p hits.map(&:name) #=> ["SOME_TAG","HOLY_TAG","MAJOR_TAG","FOO_FOO"] 描述: >查找整个文档中的所有文本节点.
或者,请注意您可以定义自己的custom XPath functions in Nokogiri回调Ruby,因此您可以假装使用XPath 2.0匹配: module FindWithRegex def self.matches(nodes,pattern,flags=nil) nodes.grep(Regexp.new(pattern,flags)) end end hits = node_set.xpath('//*[matches(text(),"d+:d+:d+")]',FindWithRegex) p hits.map(&:name) #=> ["SOME_TAG","FOO_FOO"] 但是,由于每个找到的节点都重新调用它(因此每次从字符串重新创建一个新的正则表达式),因此效率不高: require 'benchmark' Benchmark.bm(15) do |x| N = 10000 x.report('grep and map'){ N.times{ node_set.xpath("//text()").grep(/d+:d+:d+/).map(&:parent) }} x.report('custom function'){ N.times{ node_set.xpath('//*[matches(text(),FindWithRegex) }} end #=> user system total real #=> grep and map 0.437000 0.016000 0.453000 ( 0.442044) #=> custom function 1.653000 0.031000 1.684000 ( 1.694170) 您可以通过缓存正则表达式加快速度: module FindWithRegex REs = {} def self.matches(nodes,flags=nil) nodes.grep(REs[pattern] ||= Regexp.new(pattern,flags)) end end #=> user system total real #=> grep and map 0.437000 0.016000 0.453000 ( 0.442044) #=> cached regex 0.905000 0.000000 0.905000 ( 0.896090) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |