正则表达式反对 XPath 之后的标记?
Posted
技术标签:
【中文标题】正则表达式反对 XPath 之后的标记?【英文标题】:Regex against markup after XPath? 【发布时间】:2018-08-25 12:43:28 【问题描述】:一直在寻找我的问题的解决方案现在已经有一段时间了,并且已经在 regex101.com 上玩了一段时间但找不到解决方案。
我面临的问题是我必须为不同的输入选择一个字符串,因此我想使用正则表达式来从这些字符串中获取所需的数据。 正则表达式将分别来自每个字符串的配置。 (因为它们不同)
下面的字符串是通过 XPath 获得的://body/div/table/tbody/tr/td/p[5]
,但我无法再深入挖掘以检索正确的数据,或者我可以吗?
我现在用作示例的字符串如下:
<strong>Kontaktdaten des Absenders:</strong>
<br>
<strong>Name:</strong> Wanted data
<br>
<strong>Telefon:</strong>
<a dir='ltr' href='tel:XXXXXXXXX' x-apple-data-detectors='true' x-apple-data-detectors-type='telephone' x-apple-data-detectors-result='3'>XXXXXXXXX</a>
<br>
我试图从这个字符串中获取“想要的数据”
到目前为止,我的正则表达式如下:
(?<=<\/strong> )(.*)(?= <br>)
但这会返回整体:
<br> <strong>Name:</strong> Wanted data <br> <strong>Telefon:</strong> <a dir='ltr' href='tel:XXXXXXXXX' x-apple-data-detectors='true' x-apple-data-detectors-type='telephone' x-apple-data-detectors-result='3'>XXXXXXXXX</a>
我想我可以通过重复组来解决这个问题
((:?(?<=<\/strong> )(.*)(?= <br>))+)
但这会返回与没有重复组相同的输出。
我知道我可以围绕这个正则表达式构建一个 for 循环以获得相同的输出,但由于这是我必须为它执行此操作的唯一正则表达式(但这意味着我必须为所有其他数据更改它)我想知道是否可以在正则表达式中执行此操作。
感谢您迄今为止的支持。
【问题讨论】:
强制 - 像 html Agility Pack 这样的 HTML 解析器是解析 HTML 的最佳方式 - 注释。 我已经在使用 HTML Agility Pack,正如我所说,这是我可以深入挖掘我的 Html 的最深层次,因此无法以这种方式获取“想要的数据”已经编辑了 HTML 代码,以便您可以看出我的意思了(enter不应该在这里,只是一个字符串,而是为了让它更具可读性) @AlexK。是对的。 Never parse markup with regex. 您甚至可以使用 XPath。 You can finish the job with XPath alone. 我们无法告诉您如何在不知道要查找什么模式的情况下找到字符串“Wanted data”。大概它不会总是说“想要的数据”,它可能会说别的东西(或者你不会搜索它)。所以问题是,你的内容的哪些部分是固定的,哪些是可变的? 【参考方案1】:Regex is the wrong tool for parsing markup. 你手头有一个合适的 XML 解析工具 XPath。用它完成工作:
这个 XPath,
strong[.='Name:']/following-sibling::text()[1]
当附加到原始 XPath 时,
//body/div/table/tbody/tr/td/p[5]/strong[.='Name:']/following-sibling::text()[1]
将按照要求完成选择紧跟在<strong>Name:</strong>
标签后面的文本节点的工作,不需要对标记进行正则表达式修改。
【讨论】:
谢谢,这确实是解决我问题的更清洁的方法。不知道也可以使用 XPath 搜索文本。看看我是否可以在更多数据上使用它,因为目前我已经用正则表达式解决了所有问题:) 自从你的评论和链接到伟大的帖子Never parse markup with regex以来,我一直在更改许多不需要的正则表达式。但是对于以下内容,我想知道是否还有一种方法可以使用 XPath 来解决它:DataName: Herr FirstName LastName
XPath 到目前为止://body//div/div/table/tr/td/div/table/tr[3]/td/div/table/tr/td/p[1]/span
在这里我使用以下正则表达式:(?<=Herr |Frau ).*
@svenQ:很乐意帮助您找到解决其他问题的 XPath 解决方案,但请将其作为一个新问题发布——尝试在 cmets 中做太多事情会变得太麻烦。谢谢。
对不起,这是我关于 SO 的第一个问题,所以我认为它是这样做的 :) 我在这里发布了我的问题作为答案,因为我还不能打开一个新问题。
@svenQ: Np,但你会想发布一个新的问题,而不是an new answer。谢谢。【参考方案2】:
您可以尝试匹配除标记标记之外的所有内容:
(?<=<\/strong> )([^<>]*)(?= <br>)
Demo
【讨论】:
谢谢!这确实解决了我的问题并给了我想要的数据。 考虑通过单击箭头和数字附近的绿色勾号来接受答案。 很抱歉,当我回复您的问题时,@kjhughes 没有看到他的解决方案,但他的解决方案更干净地解决了我的问题。我只是在寻找错误的方向。但我仍然感谢您的正确答案。以上是关于正则表达式反对 XPath 之后的标记?的主要内容,如果未能解决你的问题,请参考以下文章
正则表达式、xpath、BeautifulSoup和JSONPath的区别?