0

我之前问过一个类似的问题,推荐 Nokogiri 作为解决方案。我用过Nokogiri,它确实工作得很好。

但由于某些原因,我必须使用正则表达式从 HTTP 响应正文中提取关键字。

关键字格式如下:

<HTML>
<HEAD> <TITLE>TestExample [Date]</TITLE></HEAD>
</HTML>

这里,Date是一个动态变量,我需要TestExample [Date]从 HTTP 响应正文中提取 ' '。此外,<title>可以是小写或大写。

假设“响应”具有 http 响应,我尝试执行以下操作:

>> response
=> "<HTML>\n<HEAD> <TITLE>TestExample [Date]</TITLE></HEAD>\n</HTML>"

然后做一个正则表达式来搜索:

>> regex
=> /<title>TestExample (.*?)<\/title>/mi

当我做 aresponse[regex]时没有结果。response.match(regex)和没有结果response.scan(regex)

如何使用 regex完成此任务?


更新:

对于此任务,此正则表达式可以正常工作:

response.match(/<title>(.*)<\/title>/mi).captures.first
4

3 回答 3

3

正如其他人所说,正则表达式不是要走的路。如果您真的一定要使用正则表达式(不仅仅是懒得重构?),这应该可以解决问题:

response.match(/<title>(.*)<\/title>/mi).captures.first
于 2013-06-10T19:44:32.957 回答
2

处理这个问题的正确方法是使用解析器。Nokogiri 将处理您提出的每一项要求,不会因大小写差异或日期差异而中断。

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<HTML>
<HEAD> <TITLE>TestExample [Date]</TITLE></HEAD>
</HTML>
EOT
doc.at('title').text
=> "TestExample [Date]"

doc = Nokogiri::HTML(<<EOT)
<HTML>
<HEAD> <TITLE>TestExample [1/1/2000]</TITLE></HEAD>
</HTML>
EOT
doc.at('title').text
=> "TestExample [1/1/2000]"

doc = Nokogiri::HTML(<<EOT)
<HTML>
<HEAD> <TiTlE>TestExample [Jan. 1, 2000]</tItLe></HEAD>
</HTML>
EOT
doc.at('title').text
=> "TestExample [Jan. 1, 2000]"

doc.title
=> "TestExample [Jan. 1, 2000]"
于 2013-06-10T20:07:54.617 回答
1

您也可以尝试使用这种模式:

/(?<=<title>)[^<]++/i

[^<]表示除 < 之外的所有字符(字符类)
[^<]+表示 1 个或多个来自该类的字符
[^<]++表示 1 个或多个来自该类的字符,并且是所有格

所有格量词通知正则表达式引擎它不需要回溯,因此性能更好。

例子:

response.match(/(?<=<title>)[^<]++/i)

这个想法是不使用点并将其替换为排除的字符类<

请注意,结果是整个模式,这里不需要使用捕获组,也不需要测试接下来会发生什么。我删除了 m 修饰符(代表 DOTALL),因为我不使用点。

我只是通过向后看来控制<title>之前的情况。

于 2013-06-10T20:09:26.347 回答