【发布时间】:2017-03-26 08:10:09
【问题描述】:
尝试提取与字符串中的模式匹配的子字符串。 例如我有像下面这样的文字
[ Pierre/NNP Vinken/NNP ]
,/,
[ 61/CD years/NNS ]
old/JJ ,/, will/MD join/VB
[ the/DT board/NN ]
as/IN
[ a/DT nonexecutive/JJ director/NN Nov./NNP 29/CD ]
./.
[ Mr./NNP Vinken/NNP ]
is/VBZ
[ chairman/NN ]
of/IN
我想提取斜杠 (/) 之前的任何内容和斜杠之后的任何内容,但不知何故,我的正则表达式提取了第一个子字符串并忽略了该行中的其余子字符串。
我的输出如下所示:
tag:Pierre/NNP Vinken - word:Pierre/NNP Vinken/NNP ->1
tag:, - word:,/, ->1
tag:61/CD years - word:61/CD years/NNS ->1
tag:old/JJ ,/, will/MD join - word:old/JJ ,/, will/MD join/VB ->1
tag:the/DT board - word:the/DT board/NN ->1
tag:as - word:as/IN ->1
tag:a/DT nonexecutive/JJ director/NN Nov./NNP 29 - word:a/DT nonexecutive/JJ director/NN Nov./NNP 29/CD ->1
tag:. - word:./. ->1
tag:Mr./NNP Vinken - word:Mr./NNP Vinken/NNP ->1
tag:is - word:is/VBZ ->1
tag:chairman - word:chairman/NN ->1
tag:of - word:of/IN ->1
但我真正想要的是下面这样的东西
tag:NNP - word:Pierre ->1
tag:NNP - word:Vinken ->1
tag:, - word:, ->1
tag:CD - word:61 ->1
.
.
etc.
我使用的代码:
while (my $line = <$fh>) {
chomp $line;
#remove square brackets
$line=~s/[\[\]]//;
while($line =~m/((\s*(.*))\/((.*)\s+))/gi)
{
$word=$1;
$tag=$2;
#remove whitespace from left and right of string
$word=~ s/^\s+|\s+$//g;
$tag=~ s/^\s+|\s+$//g;
$tags{$tag}++;
$tagHash{$tag}{$word}++;
}
}
foreach my $str (sort keys %tagHash)
{
foreach my $s (keys %{$tagHash{$str}} )
{
print "tags:$str - word: $s-> $tagHash{$str}{$s}\n";
}
}
知道为什么我的正则表达式的行为不应该是这样的
编辑:
在我正在解析的文本文件中也有通配符和标点符号,这意味着文件将具有以下内容: ''/'' “/” ,/, ./. ?/? !/! . . . 等等
所以我想捕捉所有这些东西,而不仅仅是字母和数字字符。
【问题讨论】:
-
那是因为 .* 的贪婪本性,你为什么不在 / 上进行拆分
-
全部原因是因为当你点击这样的 [./.] 时,斜线左侧的任何内容都是单词,而右侧的任何内容都是该单词的标签,在这种情况下,两者都是将是相同的,如果我将它们存储到数组中可能会令人困惑,但我认为你是对的,因为在这种情况下,数组中的奇数位置将代表标签,偶数位置将代表单词。
-
试试
\b([\w\.]+?)\/([\w\.]+)\b@kero -
或:
while( $line =~ m!([^/\s]+)/([^/\s]+)!g ) { -
试试this one:
\s*([\w\.,'"]+?)\/([\w\.,'"]+)\s*@kero