2011-08-25 107 views
1

我有一个文本文件,其中包含用单引号括起来的名称。我如何做一个正则表达式来获取文本包含的所有名称?提取文本的正则表达式

- "Lady of Spain" (uncredited) 
    Music by 'Tolchard Evans' (qv) 
    Lyrics by 'Robert Hargreaves (II)' (qv), 'Stanley Damerell' (qv) and 'Henry B. Tilsley' (qv) 
    Performed by 'Jack Haig' (qv) and 'Kenneth Connor' (qv) 

这是我能想出来的。

/(\'(.*)\')*/ 

但是,期间只匹配到换行符。所以我修改了正则表达式包括

/(\'(.*)\'.*(\n|\r\n)*)*/ 

但它仍然没有参与。请帮我弄清楚为什么我的正则表达式不起作用。

+0

您似乎不需要为该输入匹配换行符。 – TLP

+2

当单引号字符串本身包含单引号时,您的文本文件包含什么?例如Kenneth O'Conner – tadmc

回答

3

我会使用split代替:

#!/usr/bin/env perl 

while (<DATA>) { 
    chomp(); 
    @values = split(/('.*?')/); 
    foreach my $val (@values) { 
     print "$val\n" if ($val =~ m/^'/) 
    } 
} 

__DATA__ 
- "Lady of Spain" (uncredited) 
    Music by 'Tolchard Evans' (qv) 
    Lyrics by 'Robert Hargreaves (II)' (qv), 'Stanley Damerell' (qv) and 'Henry B. Tilsley' (qv) 
    Performed by 'Jack Haig' (qv) and 'Kenneth Connor' (qv) 

输出:

'Tolchard Evans' 
'Robert Hargreaves (II)' 
'Stanley Damerell' 
'Henry B. Tilsley' 
'Jack Haig' 
'Kenneth Connor' 
+1

'说for(grep/^'/,split /('.*?')/);':-)很好的使用非破坏性拆分。 – TLP

0

使用非贪婪量词:

/'(.*?)'/ 

/'([^']*)'/ 
1

你并不需要与输入的那些行匹配换行符。我认为你的问题不在于正则表达式,而在于你如何处理数据。只要您的单引号字符串不包含换行符,您就不需要对此进行补偿。

尝试使用下面的衬板,例如:

perl -nwE '$,="\n"; say /\'([^']+)\'/g;' quotes.txt 

正如你所看到的,我用的是全局选项/g获得每行的所有比赛。

进一步解释:

  • -n:假定程序围绕while (<>)环(来从文件输入)
  • -E:一个在线程序,启用所有可选功能(即 say
  • $,:将OUTPUT_FIELD_SEPARATOR设置为换行符,以便所有匹配的 以换行符分隔。

如果你有一个字符串在整个文本文件,试试这个:

my @matches = $string =~ /'([^']+)'/g; 
+0

bash:意外标记附近的语法错误'(' –

+0

@Fredrik shell搞乱了单引号..我在windows上,所以我不知道如何解决这个问题。 – TLP

+0

我知道,引用当你需要引用引号字符时有点混乱:-) –

0

你可以使用这个:

open FILE, "myfile" or die "Couldn't open file: $!"; 
#read file to sting 
while (<FILE>){ 
    $string .= $_; 
} 
close FILE; 

#match regex with right order and put to array 
while ($string =~ m/'(.*?)'/g) { 
    $hash{$1} = ++$i unless $hash{$1}; 
} 
@array = sort {$hash{$a} <=> $hash{$b}} keys %hash; 

#print array 
foreach (@array) { 
    print $_ . "\n"; 
}