【问题标题】:finding match for string in Perl在 Perl 中查找字符串的匹配项
【发布时间】:2011-11-04 15:24:35
【问题描述】:

我是 Perl 的初学者。有人可以帮助我如何从下面的脚本中正确提取数据吗?

#####################################################################
#! /usr/bin/perl
$text = "Name: Anne Lorrence Name: Burkart Name: Claire Name: Dan" ;
$match = 0 ;
while ($text =~ /Name: \b(\S+)\s+(\S+)\b/g || /Name: \b(\S+)\b/g) {
    ++ $match ;
print "Match number $match is $1 $2\n" ;
}
######################################################################

我希望我的输出是这样的:

Match number 1 is Anne MLorrence
Match number 2 is Burkart
Match number 3 is Claire 
Match number 4 is Dan

但事实上,我的脚本给了我这个:

Match number 1 is Anne MLorrence
Match number 2 is Burkart Name

我可以知道出了什么问题吗?

【问题讨论】:

  • “Anne MLorrence”中的“M”应该来自哪里,输入“Anne Lorrence”? /Name: \b(\S+)\b/g 匹配的是什么? (提示:$_,而不是 $text)。
  • 我会简单地split("/Name:\s+/) 并丢弃第一个匹配项。使用两个单独的正则表达式和if (/r1/g|| /r2/g) 在任何情况下都不起作用,因为/g 匹配指针不会保持同步。不过,您可以将其按摩成一个正则表达式。提示:使用非贪婪匹配或否定前瞻断言。

标签: perl


【解决方案1】:
$text = "Name: Anne Lorrence Name: Burkart Name: Claire Name: Dan" ;
$match = 0 ;
while ($text =~ /Name: (.+?)(?= Name:|$)/g) {
    ++ $match ;
    print "Match number $match is $1\n" ;
}

它使用非贪婪捕获和零宽度正向前瞻来分隔字段。

Match number 1 is Anne Lorrence
Match number 2 is Burkart
Match number 3 is Claire
Match number 4 is Dan

|$) 部分是替代部分。一个更容易理解的例子是(ABC|DEF),意思是“匹配‘ABC’或‘DEF’”。 $ 只是行尾符号。

perlre 文档中解释了零宽度正向前瞻,但我将尝试在此处进行总结。它是称为“Look-Around Assertions”的一类模式的一部分,这个名字非常准确。想象一下正则表达式引擎在字符串中的某个点“环顾四周”。这里使用的那个在字符串中“向前看”以获得肯定匹配。之所以称为零宽度,是因为它在模式匹配过程中不消耗任何字符串。

所以,/Name: (.+?)(?= Name:|$) 模式说:

  1. 匹配“姓名:”
  2. 尽可能少地匹配和捕获
  3. 直到您看到以下字符是“名称:”或 EOL

可能有更好的方法来解决您的任务,但这是简短而清晰的,可以让您深入了解正则表达式语言的一些较少使用的部分。 Look-Arounds 非常有用,非常值得学习。

【讨论】:

  • 非常感谢 ptomli 的及时回答,它得到了我想要的!您能帮忙解释一下 (?= Name: |$) 是什么意思吗?我不知道表达式的含义是什么,尤其是“|$”。谢谢!
  • ops... 只知道 DavidO 和 Tripleee 的回答。我真的很新鲜,你的答案对我来说有点难以应用到我的脚本中......我需要更多详细的指南,比如 ptomli 给出的示例,无论如何......谢谢:)
  • 感谢 ptomli!欣赏!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-06
  • 2015-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
相关资源
最近更新 更多