【问题标题】:Regex to capture substring between quotes正则表达式捕获引号之间的子字符串
【发布时间】:2013-07-18 20:48:13
【问题描述】:

我有以下有效的代码:(标准文本字符串)

($txid) = $content =~ m/ start (.*) stop /;
print $txid;

下面这段代码没有:(带引号的字符串)

($txid) = $content =~ m/<input name="transactionid" value="(.*)" type="hidden">/;
print $txid;

我猜问题是由引号引起的。有谁知道我该如何解决这个问题?

【问题讨论】:

  • 这个问题很可能不是带引号的。 (a) 不要用正则表达式解析 HTML,这势必会产生脆弱的解决方案。 (b) 你有什么意见?给我们举个例子。
  • "It's not working" 不是描述问题的好方法。
  • 这里输入的内容太大了,是HTML的网页。第一个我刚刚做了一个字符串“start hello stop”,它正确返回了“hello”。第二个只是返回一个空变量。我检查了 $content 填充了正确的数据,我只需要获取隐藏字段“transactionid”的值。
  • 也许您应该提供一个示例输入,其中包含可以粘贴到您的问题中的相关数据。理想情况下,您应该写一个sscce,以便人们可以直接进入,运行您的代码并回答您的问题。也就是说,如果您想要快速而好的答案。
  • 不要使用正则表达式解析 HTML。您无法使用正则表达式可靠地解析 HTML,并且您将面临悲伤和挫败感。一旦 HTML 与您的期望发生变化,您的代码就会被破坏。有关如何使用已经编写、测试和调试过的 Perl 模块正确解析 HTML 的示例,请参阅 htmlparsing.com/perl

标签: regex perl html-parsing


【解决方案1】:

默认情况下,* 量词是“贪婪的”,这意味着(.*) 将匹配它可能匹配的所有内容。要限制它以使其尽可能少地匹配,即仅在字符串中出现下一个双引号之前,请向其添加 ?,因此:

($txid) = $content =~ m/<input name="transactionid" value="(.*?)" type="hidden">/;

假设value 属性的值不包含转义的双引号,这将产生您想要的结果。

(当然,如果有 转义双引号,则没有正则表达式可以可靠地仅提取感兴趣的字符串而没有其他内容。这就是人们告诉您不要使用正则表达式的原因作为您解析平衡文本的唯一工具。另一方面,鉴于您在这里的目的很简单,您可能会侥幸成功 - 但对于任何事情,我的意思是 anything,这需要比这更复杂的 HTML 或 XML 处理,使用 XML 解析器。)

【讨论】:

  • @user1796225 很高兴能为您提供帮助。也就是说,您收到的关于使用正则表达式解析 HTML 的警告是多年的咒骂、扯皮和普遍痛苦的结果,您最好遵守它们。您在这里只能侥幸逃脱,因为您有一个非常简单的问题;如果您的要求稍微复杂一点,我会给您一个 HTML::TreeBuilder 示例。当然,欢迎您忽略此建议,但这样做有风险。
  • 没问题,感谢您的建议。就像你说的,这是一项简单的任务,也是我唯一需要在整个软件中解析 HTML 的时候。将来,如果我每次都解析 HTML,我会牢记这个建议。 :-)
  • 你应该使用匹配每个字符;您应该使用除分隔符之外的所有内容:([^"]*)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 2014-08-27
  • 2023-01-10
  • 2019-05-22
相关资源
最近更新 更多