Regex 使用quotemeta()在Perl中进行精确字符串匹配

Regex 使用quotemeta()在Perl中进行精确字符串匹配,regex,perl,Regex,Perl,我正在尝试在Perl中使用。以下是我试图找到的字符串和模式的代码: open FH, "<query.txt"; @foo = <FH>; my $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis PEG-Intron (Schering Corp) specimen from a human testicular embryonal carcinoma w

我正在尝试在Perl中使用。以下是我试图找到的字符串和模式的代码:

open FH, "<query.txt";

@foo = <FH>;
my $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis 
PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with
 elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp)";

foreach my $word(@foo) {
chomp $word;
if ($bar =~ /\b\Q$word\E\b/i)
{
print "$word\n";
}
}
我的代码似乎不起作用,我不明白出了什么问题

更新:

If $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis 
PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with
 elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp)
specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma
was successfully  xenotransplanted into nude mice and maintained until the tenth animal
passage. Electron microscopy of the tumors in nude mice revealed details Secremax,
SecreFlo consistent with their epithelial origin.";
query.txt还包含以下术语:

 pa
 the
 scopy
 ealed

\b
仅在单词边界处匹配,但某些模式以括号结尾,而括号不是单词边界。相反,请使用regex
/(?确保匹配的前面或后面没有单词。

\b
仅在单词边界处匹配,但某些模式以括号结束,而括号不是单词边界。请改用regex
/(?这确保了您的匹配前面或后面没有单词。

问题在于您搜索时使用的
\b
\b
仅在
\w
字符和非
\w
字符(或字符串的开头或结尾)之间匹配。
不是单词字符,空格也不是,
\)\b
”不匹配

解决方案取决于您正试图做什么。也许你想要

$bar =~ /(?<!\w)\Q$word\E(?!\w)/i

这意味着“只要找到
$word
,我不在乎有什么东西碰到它。”

问题在于你搜索时使用的
\b
\b
仅在
\w
字符和非
\w
字符(或字符串的开头或结尾)之间匹配。由于
不是单词字符,也不是空格,
\)\b
不匹配

解决方案取决于您正试图做什么。也许你想要

$bar =~ /(?<!\w)\Q$word\E(?!\w)/i

这意味着“只要找到
$word
,我不在乎有什么东西碰到它。”

我添加了
使用严格
使用警告
,在
@foo
之前插入
my
,并在循环中插入一条print语句:

foreach my $word (@foo)
{
    chomp $word;
    print "Checking $word:\n";
    if ($bar =~ /\b\Q$word\E\b/i)
    {
        print "Match $word\n";
    }
}
然后,我从MacOS X 10.7.2(Lion)上的Perl 5.12.3获得了以下输出:

因此,当
$word
不包含regex元字符时,模式匹配对我有效。然而,它并不像“符号不起作用”那么简单;我将
query.txt
文件更改为:

Elspar .Merck . Co. Inc.
Thyrogen .Genzyme Inc.
PEG-Intron  .Schering Corp.
Secremax, SecreFlo
Secremax, SecreFlo .Repligen Corp.
结果和以前一样。这使得
\b
符号成为可疑符号;某些字符串与单词边界不匹配。如果我从正则表达式中删除两个
\b
标记,那么我得到:

Checking Elspar (Merck & Co. Inc):
Match Elspar (Merck & Co. Inc)
Checking Thyrogen (Genzyme Inc):
Match Thyrogen (Genzyme Inc)
Checking PEG-Intron  (Schering Corp):
Match PEG-Intron  (Schering Corp)
Checking Secremax, SecreFlo:
Match Secremax, SecreFlo
Checking Secremax, SecreFlo (Repligen Corp):
Match Secremax, SecreFlo (Repligen Corp)
您可以保留第一个
\b
;这给出了同样的结果。右括号会带来问题,因为当后跟空格(如文本中的空格)时,不会标记单词和非单词之间的边界


对经修正的问题的答复 此代码似乎按要求工作。基本上,它查看如何构造查询:

use strict;
use warnings;

open FH, "<query.txt";

my @foo = <FH>;
#my $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp)";

my $bar =  "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp) specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma was successfully  xenotransplanted into nude mice and maintained until the tenth animal passage. Electron microscopy of the tumors in nude mice revealed details Secremax, SecreFlo consistent with their epithelial origin.";

foreach my $word (@foo)
{
    chomp $word;
    print "Checking $word:\n";
    my ($pfx, $sfx) = ('', '');
    $pfx = '\b' if ($word =~ /^\w/);
    $sfx = '\b' if ($word =~ /\w$/);
    if ($bar =~ /$pfx\Q$word\E$sfx/i)
    {
        print "Match $word\n";
    }
}

在我看来这是正确的。它是否在所有可能的情况下都有效有待讨论。您可能需要担心
(Secremax,Secreflow(Repligen Corp))
是否与其中包含“Repligen”的模式匹配,如果不匹配,您必须对匹配的构成给出非常严格的定义。

我添加了
使用strict
使用警告
,在
@foo
之前插入
my
,并在循环中插入一条print语句:

foreach my $word (@foo)
{
    chomp $word;
    print "Checking $word:\n";
    if ($bar =~ /\b\Q$word\E\b/i)
    {
        print "Match $word\n";
    }
}
然后,我从MacOS X 10.7.2(Lion)上的Perl 5.12.3获得了以下输出:

因此,当
$word
不包含regex元字符时,模式匹配对我有效。然而,它并不像“符号不起作用”那么简单;我将
query.txt
文件更改为:

Elspar .Merck . Co. Inc.
Thyrogen .Genzyme Inc.
PEG-Intron  .Schering Corp.
Secremax, SecreFlo
Secremax, SecreFlo .Repligen Corp.
结果和以前一样。这使得
\b
符号成为可疑符号;某些字符串与单词边界不匹配。如果我从正则表达式中删除两个
\b
标记,那么我得到:

Checking Elspar (Merck & Co. Inc):
Match Elspar (Merck & Co. Inc)
Checking Thyrogen (Genzyme Inc):
Match Thyrogen (Genzyme Inc)
Checking PEG-Intron  (Schering Corp):
Match PEG-Intron  (Schering Corp)
Checking Secremax, SecreFlo:
Match Secremax, SecreFlo
Checking Secremax, SecreFlo (Repligen Corp):
Match Secremax, SecreFlo (Repligen Corp)
您可以保留第一个
\b
;这给出了同样的结果。右括号会带来问题,因为当后跟空格(如文本中的空格)时,不会标记单词和非单词之间的边界


对经修正的问题的答复 此代码似乎按要求工作。基本上,它查看如何构造查询:

use strict;
use warnings;

open FH, "<query.txt";

my @foo = <FH>;
#my $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp)";

my $bar =  "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp) specimen from a human testicular embryonal carcinoma with elements of a choriocarcinoma was successfully  xenotransplanted into nude mice and maintained until the tenth animal passage. Electron microscopy of the tumors in nude mice revealed details Secremax, SecreFlo consistent with their epithelial origin.";

foreach my $word (@foo)
{
    chomp $word;
    print "Checking $word:\n";
    my ($pfx, $sfx) = ('', '');
    $pfx = '\b' if ($word =~ /^\w/);
    $sfx = '\b' if ($word =~ /\w$/);
    if ($bar =~ /$pfx\Q$word\E$sfx/i)
    {
        print "Match $word\n";
    }
}
在我看来这是正确的。它是否在所有可能的情况下都有效有待讨论。您可能需要担心
(Secremax,Secreflow(Repligen Corp))
是否与其中包含“Repligen”的模式匹配,如果不匹配,您必须对匹配的构成给出更严格的定义。

使用quotemeta以便:

open FH, "<query.txt";

@foo = <FH>;
my $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis 
PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with
 elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp)";

foreach my $word(@foo) {
    chomp $word;

    my $quoted_word = quotemeta($word);

    if ($bar =~ m/$quoted_word/i){
        print "$word\n";
    }
}
打开FH,”使用quotemeta以便:

open FH, "<query.txt";

@foo = <FH>;
my $bar = "A lymph node Elspar (Merck & Co. Inc) Thyrogen (Genzyme Inc) metastasis 
PEG-Intron  (Schering Corp) specimen from a human testicular embryonal carcinoma with
 elements of a choriocarcinoma Secremax, SecreFlo Secremax, SecreFlo (Repligen Corp)";

foreach my $word(@foo) {
    chomp $word;

    my $quoted_word = quotemeta($word);

    if ($bar =~ m/$quoted_word/i){
        print "$word\n";
    }
}

openfh,“regex中只使用一次的
$sam
变量是什么?你的意思是在那里写$word吗?是的,它的意思是$word。我编辑了它。当你错误地检查你的
open
函数时会发生什么?文件会很好地打开。我检查了所有的东西。我认为是正则表达式导致了错误。如果我更新的响应不是您想要的,那么您应该给出示例输入并解释您希望看到的确切示例输出。正则表达式中只使用一次的
$sam
变量是什么?你的意思是在那里写$word吗?是的,它的意思是$word。我编辑了它。当你错误地检查你的
open
函数时会发生什么?文件会很好地打开。我检查了所有的东西。我认为是正则表达式导致了错误。如果我更新的响应不是你想要的,那么你应该给出你的样本输入,并解释你想要看到的确切样本输出。好吧,我想我需要修改一下我的问题。让我再添加一些我正在寻找的单词和字符串。我想找到精确的单词匹配。这真的很有帮助。你能不能也帮我,如果情况是找到确切的字符串,而不是部分的话。也就是说,我只想匹配query.txt中的完整单词,而不是部分单词。如何修改正则表达式的代码。谢谢嗯,我想我需要修改我的问题