当前位置:  开发笔记 > 后端 > 正文

类似正则表达式匹配的xpath表达式?

如何解决《类似正则表达式匹配的xpath表达式?》经验,为你挑选了2个好方法。

我想在具有特定模式的html doc中搜索div id.我想在正则表达式中匹配此模式:

foo_([[:digit:]]{1.8})

使用xpath.上述模式的xpath等价物是多少?

我坚持了//div[@id="foo_,然后呢?如果有人可以继续为其表达法律意见.

编辑

对不起,我想我必须详细说明.实际上它不是foo_,它是post_message_

顺便说一下,我使用mechanize/nokogiri(红宝石)

这是片段:

html_doc = Nokogiri::HTML(open(myfile))
message_div =  html_doc.xpath('//div[substring(@id,13) = "post_message_" and substring-after(@id, "post_message_") => 0 and substring-after(@id, "post_message_") <= 99999999]') 

仍然失败了.错误信息:

无法评估表达式' //div[substring(@id,13) = "post_message_" and substring-after(@id, "post_message_") => 0 and substring-after(@id, "post_message_") <= 99999999]'(Nokogiri :: XML :: XPath :: SyntaxError)

Tomalak.. 15

怎么样(更新):

XPath 1.0:

"//div[substring-before(@id, '_') = 'foo' 
       and substring-after(@id, '_') >= 0 
       and substring-after(@id, '_') <= 99999999]"

编辑#2:OP对问题进行了更改.以下,更加简化的XPath 1.0表达式对我有用:

"//div[substring(@id, 1, 13) = 'post_message_' 
       and substring(@id, 14) >= 0 
       and substring(@id, 14) <= 99999999]"

XPath 2.0有一个方便的matches()功能:

"//div[matches(@id, '^foo_\d{1,8}$')]"

除了更好的可移植性之外,我希望数值表达式(XPath 1.0样式)的性能优于正则表达式测试,尽管这只会在处理大型数据集时变得明显.


原始版本的答案:

"//div[substring-before(@id, '_') = 'foo' 
       and number(substring-after(@id, '_')) = substring-after(@id, '_') 
       and number(substring-after(@id, '_')) >= 0 
       and number(substring-after(@id, '_')) <= 99999999]"

number()函数的使用是不必要的,因为数学比较运算符隐式地将它们的参数强制转换为数字,任何非数字都将变为NaN并且大于/小于测试将失败.

我还删除了尖括号的编码,因为这是XML要求,而不是XPath要求.



1> Tomalak..:

怎么样(更新):

XPath 1.0:

"//div[substring-before(@id, '_') = 'foo' 
       and substring-after(@id, '_') >= 0 
       and substring-after(@id, '_') <= 99999999]"

编辑#2:OP对问题进行了更改.以下,更加简化的XPath 1.0表达式对我有用:

"//div[substring(@id, 1, 13) = 'post_message_' 
       and substring(@id, 14) >= 0 
       and substring(@id, 14) <= 99999999]"

XPath 2.0有一个方便的matches()功能:

"//div[matches(@id, '^foo_\d{1,8}$')]"

除了更好的可移植性之外,我希望数值表达式(XPath 1.0样式)的性能优于正则表达式测试,尽管这只会在处理大型数据集时变得明显.


原始版本的答案:

"//div[substring-before(@id, '_') = 'foo' 
       and number(substring-after(@id, '_')) = substring-after(@id, '_') 
       and number(substring-after(@id, '_')) >= 0 
       and number(substring-after(@id, '_')) <= 99999999]"

number()函数的使用是不必要的,因为数学比较运算符隐式地将它们的参数强制转换为数字,任何非数字都将变为NaN并且大于/小于测试将失败.

我还删除了尖括号的编码,因为这是XML要求,而不是XPath要求.



2> Dimitre Nova..:

正如已经指出的那样,在XPath 2.0中,将标准的正则表达式功能与函数一样使用是很好的matches().

一个可能的XPath 1.0解决方案:

//div[starts-with(@id, 'post_message_')
    and
      string-length(@id) = 21
    and
      translate(substring-after(@id, 'post_message_'), 
                '0123456789', 
                ''
                )
     =
      ''
      ] 

请注意以下事项:

    使用标准的XPath函数starts-with().

    使用标准的XPath函数string-length().

    使用标准的XPath函数substring-after().

    使用标准的XPath函数translate().

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有