【问题标题】:Regex working in tester, but not in Sublime Text 3正则表达式在测试器中工作,但不在 Sublime Text 3 中
【发布时间】:2018-02-07 22:23:12
【问题描述】:

在字符串中

 <td class="useragent"><a href="/useragents/parse/627832-chrome-windows-blink">Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36</a></td>

我正在尝试提取并复制到剪贴板

Mozilla/5.0 (Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko) Chrome/60.0.3112.113 Safari/537.36

使用https://regexr.com/ 的正则表达式测试器,我发现这个正则表达式完成了我所寻求的:

(?<=<td class="useragent"><a href=".*">).*(?=</a>)

当我在 Sublime Text 中尝试它时,它没有。我猜这与 RegEx 的不同“风格”有关,那么如何更改此 RegEx 以使用 Sublime Text?

【问题讨论】:

  • 试试这个:&lt;td\s+class="useragent".*&gt;&lt;a\s+.*&gt;(.*)&lt;/a&gt;&lt;/td&gt;
  • 这是什么(?&lt;=.*) ?显示一个永久链接,指向您测试此特定正则表达式的位置。
  • @AntonioDias 我在搜索时收到消息“无法在选择中找到 (.*)一个 HTML 文件,其中包含与我发布的内容相似的字符串
  • 可能与多行匹配有关。不幸的是,我这里没有 Sublime,我的猜测完全基于正则表达式。
  • @AntonioDias 无论如何,谢谢,幸运的是其他人能够帮助我解决这个问题。我很欣赏快速响应,即使它在我的情况下不起作用。

标签: regex sublimetext3


【解决方案1】:

Sublime Text 3 正则表达式解决方案

您不能在 PCRE 正则表达式中使用未知长度的lookbehind(它是在 Sublime Text 3 中使用的正则表达式库)。但是,由于您使用的是正向后视,您可以改用 \K 匹配重置运算符(它将丢弃匹配内存缓冲区中到目前为止匹配的所有文本)。

此外,您可能会考虑一些增强功能:

  • ".*" 可能会跨标签溢出,请改用"[^"]*"
  • .*&lt;/a&gt; 可以到达最后一行 &lt;/a&gt;,使用 .*?&lt;/a&gt; 到达第一个
  • 如果&lt;a&gt; 节点中有换行符,请使用(?s) DOTALL 内联修饰符使.*? 跨行匹配

使用

(?s)<td class="useragent"><a href="[^"]*">\K.*?(?=</a>)
                                          ^^ 

请参阅regex demo

ST3 测试:

请参阅 regular-expressions.info 上的Keep The Text Matched So Far out of The Overall Regex Match

使用 DOM 解析的 PHP 回退

您实际上应该谨慎从任意 HTML 解析数据。如果你想从一个大的 HTML 中获取你需要的所有文本,你应该考虑使用一个成熟的 HTML DOM 支持技术。这是一个使用 PHP (see an online PHP demo) 的示例:

$text = <<<EOD
<td class="useragent"><a href="/useragents/parse/627832-chrome-windows-blink">Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36</a></td>
EOD;
$domDocument = new DOMDocument;
$domDocument->loadHTML($text, LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($domDocument);
$nodes = $xpath->query('//td[@class="useragent"]/a');
$res = [];
foreach($nodes as $txt) { 
   array_push($res, $txt->textContent);
}
print_r($res);

结果:

Array
(
    [0] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
)

这里,$text 是您的 HTML 文本,//td[@class="useragent"]/a 是一个 XPath,它获取 class 属性值等于 useragent 的所有 td 节点,然后在其中获取 a 节点。实际文本以$txt-&gt;textContent 返回。

【讨论】:

  • 我在在搜索充满我发布的相同模式的 HTML 文件时,Sublime Text 窗口的底部。
  • &lt;a ...&gt;... &lt;/a&gt; 内部是否有换行符?
  • Stribizew 不,我编辑了我的问题以删除它们,不确定它们在我的示例中是如何结束的。
  • regex101.com/r/50wLmH/1,这是你在ST3中应该得到的。我还为您的示例数据添加了 ST3 屏幕截图。
  • @DavidStampher 我还添加了一个使用 DOM 使用 PHP 从 HTML 中解析出必要细节的示例。不知道它是否有帮助,但这比使用正则表达式更安全。
【解决方案2】:

我在这里只有 Python,我针对您发布的字符串测试了&lt;td class="useragent"&gt;&lt;a .*&gt;(.*)&lt;/a&gt;&lt;/td&gt;,它可以工作。看看

>>> import re
>>> agent=re.compile(r'<td class="useragent"><a .*>(.*)</a></td>')
>>> s='<td class="useragent"><a href="/useragents/parse/627832-chrome-windows-blink">Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36</a></td>'
>>> agent.findall(s)
['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36']
>>> 

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多