要在grepped的行中多次出现字符串

时间:2014-06-23 09:50:19

标签: perl

我有两个问题。

1:如果我有这样的系列“水果:芒果香蕉”,我想捕捉“芒果香蕉”部分并将其分配给另一个变量。目前我正在关注此事,

if(/$line == Fruits:\s(\w+)/){
myFav=$1;
}

但它只返回“芒果”而不是“芒果香蕉”。任何人都可以建议如何获得由空格分隔的完整水果列表。

2:如果我在同一行重复了一些字符串,我想捕获所有出现的内容。

例如:如果我有一条像“我有水果:芒果和水果的颜色:香蕉是绿色的”这一行。我想同时捕捉芒果和香蕉的价值。

if(/$line == Fruit:\s(\w+)/){
myFav=$1;
}

通常,上面的代码在第一次出现“Fruit:”后停止搜索。任何人都可以帮助以上两个?

提前致谢:)

5 个答案:

答案 0 :(得分:1)

一种解决方案是依靠您的水果名称大写的事实。

但是,我很想倾向于使用两个正则表达式,一个用于水果,一个用于水果。

use strict;
use warnings;

while (<DATA>) {
    chomp;
    while (/Fruits?: ((?:[A-Z]\w*\s*)+)(?<!\s)/g) {
        print "Line $. - '$1'\n";
    }
}

__DATA__
Fruits: Mango Banana
I have Fruit: Mango and the color of the Fruit: Banana is green

输出:

Line 1 - 'Mango Banana'
Line 2 - 'Mango'
Line 2 - 'Banana'

答案 1 :(得分:0)

请改用:([\w\s]+)

if($line =~ /Fruits:\s([\w\s]+)/) {
    $myFav = $1;
}

始终:

use strict;
use warnings;

答案 2 :(得分:0)

$line="I have Fruit: Mango and the color of the Fruit: Banana is green";
@found=($line=~m/Fruit: \w+/g); # Make sure to use g operator, finds all matches in $line
for each $s (@found)
    {print "$s\n";
    }

答案 3 :(得分:0)

1 /正则表达式只返回“芒果”的原因是\ w +与“单词”字符匹配。这是数字,字母和下划线(即在Perl符号名称中有效的字符)。如果你想匹配两个水果名称之间的空格,那么你需要在正则表达式中添加一个空格(或者更好的是,\ s匹配所有空格)。您可能希望将这两个原子放在一个字符类中。

/Fruit:\s([\w\s]+)/

2 /默认情况下,匹配运算符仅匹配输入字符串中第一次出现的正则表达式。为了匹配所有这些,您需要将/g选项添加到匹配运算符。

/Fruit:\s([\w\s]+)/g

您可能会觉得有用的其他一些注意事项:

  • Perl regex tutorial是学习这些东西的好方法
  • Perl regex documentation包含所有血腥细节。
  • Perl operator documentation解释了匹配运算符。
  • 在您的所有代码中添加use strictuse warnings是一个很好的习惯。
  • 使用绑定运算符(=~)而不是赋值运算符(=)再次匹配字符串。输入字符串和绑定运算符在匹配运算符之外。

    if($ line =〜/ Fruits:\ s(\ w +)/){

答案 4 :(得分:0)

在您的第一篇文章中,您正在使用:

if ( /$line == Fruits:\s(\w+)/ ) {

首先,您应该使用~=而不是==来表示正则表达式。其次,你在正则表达式周围加上斜杠:

if ( $line ~= /Fruits:\s(\w+)/ ) {

现在,\w+用于,其中包括字母,数字,下划线以及它。它与空格不匹配。

你有:

Fruits: Mango Banana

因此,\w+将匹配Mango,但会在Mango之后停止匹配空格。

如果你想匹配两者:

if ( $line =~ /^Fruits:\s+(.+)/ ) {

注意.将匹配任何字符,包括空格。插头符号表示匹配至少一个空格。星号匹配零或更多。注意我也使用\s+而不是\s。这样,如果在Fruits之后有多个空格,您就会匹配。

在你的第二个例子中,你可以这样做:

my @fruits = $line =~ /Fruits:\s+(\S+)/g

最后的g允许多个匹配。否则,只会使用第一个。 \S表示包含可能破折号的所有非空白区域。这会将您的匹配项放入数组@fruits。阅读Regular Expression Tutorial。它会帮助您了解更好的内容。

始终在您的计划中使用use strict;use warnings;。它可以帮助您发现错误。您必须使用my声明变量,但这是值得的。