Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 匹配不在引号之间的表达式_Regex_Perl - Fatal编程技术网

Regex 匹配不在引号之间的表达式

Regex 匹配不在引号之间的表达式,regex,perl,Regex,Perl,我正在尝试从字符串中提取表达式。但是我需要这个表达式不能在引号之间 例如,我需要能够从此类字符串中提取return、if和eq(perl关键字):return3+4 if$string eq“time is eq” 我不检索时间,即使它是一个关键字,因为它位于引号之间 到目前为止,我一直在尝试: m/(((“(\\”[^“])*”)(^\s |$\n)/g 我还尝试检查字符串的结尾,看看是否有偶数/奇数个引号 第一种解决方案的问题是,如果先有空格,然后是关键字,则它与关键字不匹配。 第二种解

我正在尝试从字符串中提取表达式。但是我需要这个表达式不能在引号之间

例如,我需要能够从此类字符串中提取
return
if
eq
(perl关键字):
return3+4 if$string eq“time is eq”

我不检索
时间
,即使它是一个关键字,因为它位于引号之间

到目前为止,我一直在尝试:

  • m/(((“(\\”[^“])*”)(^\s |$\n)/g

  • 我还尝试检查字符串的结尾,看看是否有偶数/奇数个引号

第一种解决方案的问题是,如果先有空格,然后是关键字,则它与关键字不匹配。 第二种解决方案的问题是,如果字符串中有第二个关键字,并且第二个关键字后面的引号之间有一个字符串,则最新的关键字将不匹配

我想知道如何解决这个问题我已经为此工作了一段时间,它让我发疯了!:)

谢谢大家!

PS:有人问我关键词列表,这里是:

my $keywords = qr/(-A|END|length|setpgrp|-B|endgrent|link|setpriority|-b|endhostent|listen|setprotoent|-C|endnetent|local|setpwent|-c|endprotoent|localtime|setservent|-d|endpwent|log|setsockopt|-e|endservent|lstat|shift|-f|eof|map|shmctl|-g|eval|mkdir|shmget|-k|exec|msgctl|shmread|-l|exists|msgget|shmwrite|-M|exit|msgrcv|shutdown|-O|fcntl|msgsnd|sin|-o|fileno|my|sleep|-p|flock|next|socket|-r|fork|not|socketpair|-R|format|oct|sort|-S|formline|open|splice|-s|getc|opendir|split|-T|getgrent|ord|sprintf|-t|getgrgid|our|sqrt|-u|getgrnam|pack|srand|-w|gethostbyaddr|pipe|stat|-W|gethostbyname|pop|state|-X|gethostent|pos|study|-x|getlogin|print|substr|-z|getnetbyaddr|printf|symlink|abs|getnetbyname|prototype|syscall|accept|getnetent|push|sysopen|alarm|getpeername|quotemeta|sysread|atan2|getpgrp|rand|sysseek|AUTOLOAD|getppid|read|system|BEGIN|getpriority|readdir|syswrite|bind|getprotobyname|readline|tell|binmode|getprotobynumber|readlink|telldir|bless|getprotoent|readpipe|tie|break|getpwent|recv|tied|caller|getpwnam|redo|time|chdir|getpwuid|ref|times|CHECK|getservbyname|rename|truncate|chmod|getservbyport|require|uc|chomp|getservent|reset|ucfirst|chop|getsockname|return|umask|chown|getsockopt|reverse|undef|chr|glob|rewinddir|UNITCHECK|chroot|gmtime|rindex|unlink|close|goto|rmdir|unpack|closedir|grep|say|unshift|connect|hex|scalar|untie|cos|index|seek|use|crypt|INIT|seekdir|utime|dbmclose|int|select|values|dbmopen|ioctl|semctl|vec|defined|join|semget|wait|delete|keys|semop|waitpid|DESTROY|kill|send|wantarray|die|last|setgrent|warn|dump|lc|sethostent|write|each|lcfirst|setnetent|__DATA__|else|lock|qw|__END__|elsif|lt|qx|__FILE__|eq|m|s|__LINE__|exp|ne|sub|__PACKAGE__|for|no|tr|and|foreach|or|unless|cmp|ge|package|until|continue|gt|q|while|CORE|if|qq|xor|do|le|qr|y|ARGV|STDERR|STDOUT|ARGVOUT|STDIN)/;
一个想法:

搜索并替换为空白:

".*?"|\$\w+
这将删除所有变量字符串,即以
$
开头的字符串和双引号内的所有单词

在此之后,您可以使用普通正则表达式查找所有要匹配的单词:

/(-A|END|length|setpgrp|-B|endgrent|link|setpriority|-b|endhostent|listen|setprotoent|-C|endnetent|local|setpwent|-c|endprotoent|localtime|setservent|-d|endpwent|log|setsockopt|-e|endservent|lstat|shift|-f|eof|map|shmctl|-g|eval|mkdir|shmget|-k|exec|msgctl|shmread|-l|exists|msgget|shmwrite|-M|exit|msgrcv|shutdown|-O|fcntl|msgsnd|sin|-o|fileno|my|sleep|-p|flock|next|socket|-r|fork|not|socketpair|-R|format|oct|sort|-S|formline|open|splice|-s|getc|opendir|split|-T|getgrent|ord|sprintf|-t|getgrgid|our|sqrt|-u|getgrnam|pack|srand|-w|gethostbyaddr|pipe|stat|-W|gethostbyname|pop|state|-X|gethostent|pos|study|-x|getlogin|print|substr|-z|getnetbyaddr|printf|symlink|abs|getnetbyname|prototype|syscall|accept|getnetent|push|sysopen|alarm|getpeername|quotemeta|sysread|atan2|getpgrp|rand|sysseek|AUTOLOAD|getppid|read|system|BEGIN|getpriority|readdir|syswrite|bind|getprotobyname|readline|tell|binmode|getprotobynumber|readlink|telldir|bless|getprotoent|readpipe|tie|break|getpwent|recv|tied|caller|getpwnam|redo|time|chdir|getpwuid|ref|times|CHECK|getservbyname|rename|truncate|chmod|getservbyport|require|uc|chomp|getservent|reset|ucfirst|chop|getsockname|return|umask|chown|getsockopt|reverse|undef|chr|glob|rewinddir|UNITCHECK|chroot|gmtime|rindex|unlink|close|goto|rmdir|unpack|closedir|grep|say|unshift|connect|hex|scalar|untie|cos|index|seek|use|crypt|INIT|seekdir|utime|dbmclose|int|select|values|dbmopen|ioctl|semctl|vec|defined|join|semget|wait|delete|keys|semop|waitpid|DESTROY|kill|send|wantarray|die|last|setgrent|warn|dump|lc|sethostent|write|each|lcfirst|setnetent|__DATA__|else|lock|qw|__END__|elsif|lt|qx|__FILE__|eq|m|s|__LINE__|exp|ne|sub|__PACKAGE__|for|no|tr|and|foreach|or|unless|cmp|ge|package|until|continue|gt|q|while|CORE|if|qq|xor|do|le|qr|y|ARGV|STDERR|STDOUT|ARGVOUT|STDIN)/g

如果你想以一种特殊的方式处理单引号和双引号,答案是尝试匹配它们,就像匹配关键字一样。然后你只需执行额外的步骤,根据捕获的内容筛选所有匹配项

另外两个提示

  • 不要将捕获组
    (…)
    包含在缓存的正则表达式
    qr{}
    中,该正则表达式将被插入到更大的正则表达式中。而是使用非捕获组
    (?:…)
    。这是因为您希望在执行测试时能够准确地看到捕获的内容,而无需向上滚动以确定所包含正则表达式的确切编码
  • 尝试匹配特定单词时,不要忘记单词边界
    \b
以下是我如何记录您的尝试:

use strict;
use warnings;

my $singlequote_re = qr{'(?:(?>[^']+)|\\.)*'};
my $doublequote_re = qr{"(?:(?>[^"]+)|\\.)*"};
my $keywords_re = qr/(?:-A|END|length|setpgrp|-B|endgrent|link|setpriority|-b|endhostent|listen|setprotoent|-C|endnetent|local|setpwent|-c|endprotoent|localtime|setservent|-d|endpwent|log|setsockopt|-e|endservent|lstat|shift|-f|eof|map|shmctl|-g|eval|mkdir|shmget|-k|exec|msgctl|shmread|-l|exists|msgget|shmwrite|-M|exit|msgrcv|shutdown|-O|fcntl|msgsnd|sin|-o|fileno|my|sleep|-p|flock|next|socket|-r|fork|not|socketpair|-R|format|oct|sort|-S|formline|open|splice|-s|getc|opendir|split|-T|getgrent|ord|sprintf|-t|getgrgid|our|sqrt|-u|getgrnam|pack|srand|-w|gethostbyaddr|pipe|stat|-W|gethostbyname|pop|state|-X|gethostent|pos|study|-x|getlogin|print|substr|-z|getnetbyaddr|printf|symlink|abs|getnetbyname|prototype|syscall|accept|getnetent|push|sysopen|alarm|getpeername|quotemeta|sysread|atan2|getpgrp|rand|sysseek|AUTOLOAD|getppid|read|system|BEGIN|getpriority|readdir|syswrite|bind|getprotobyname|readline|tell|binmode|getprotobynumber|readlink|telldir|bless|getprotoent|readpipe|tie|break|getpwent|recv|tied|caller|getpwnam|redo|time|chdir|getpwuid|ref|times|CHECK|getservbyname|rename|truncate|chmod|getservbyport|require|uc|chomp|getservent|reset|ucfirst|chop|getsockname|return|umask|chown|getsockopt|reverse|undef|chr|glob|rewinddir|UNITCHECK|chroot|gmtime|rindex|unlink|close|goto|rmdir|unpack|closedir|grep|say|unshift|connect|hex|scalar|untie|cos|index|seek|use|crypt|INIT|seekdir|utime|dbmclose|int|select|values|dbmopen|ioctl|semctl|vec|defined|join|semget|wait|delete|keys|semop|waitpid|DESTROY|kill|send|wantarray|die|last|setgrent|warn|dump|lc|sethostent|write|each|lcfirst|setnetent|__DATA__|else|lock|qw|__END__|elsif|lt|qx|__FILE__|eq|m|s|__LINE__|exp|ne|sub|__PACKAGE__|for|no|tr|and|foreach|or|unless|cmp|ge|package|until|continue|gt|q|while|CORE|if|qq|xor|do|le|qr|y|ARGV|STDERR|STDOUT|ARGVOUT|STDIN)/;

while (<DATA>) {
    print "Line = $_";
    while (m{($singlequote_re)|($doublequote_re)|(\b$keywords_re\b)}g) {
        my $singlequote = $1;
        my $doublequote = $2;
        my $keyword = $3;

        if (defined $singlequote) {
            print "  Single quote = <$singlequote>\n";

        } elsif (defined $doublequote) {
            print "  Double quote = <$doublequote>\n";

        } elsif (defined $keyword) {
            print "  Keyword = <$keyword>\n";
        }
    }
}

__DATA__
return 3 + 4 if $string eq "time is eq";
使用严格;
使用警告;
我的$singlequote\u re=qr{'(?:(?>[^']+)\124;\\)*';
我的$doublequote\u re=qr{“(?:(?>[^”]+)\124;\\)*”;
我的$keywords\u re=qr/(以下?::::)A(A)A(124)结束,结束,结束,结束,结束,结束,结束,长度,长度,长度,长度,长度,长度,设置PGRP 124::::::::::::::::::::::::::::::)A(A)A(A)A(A)A(A)A)A(A)A)A(A)A(A)A)A(A)A(A)A)A)A(A)A)和B(A)A)结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束,结束shmctl |-g | eval | mkdir | shmget |-k | exec | msgctl | shmread |-l | exists | msgget | shmwrite |-M | exit | msgrcv shutdown |-O | fcntl | msgsnd | sin O | fileno | my|(1244)不知道;袜子对(1244)睡睡睡睡睡睡(1244)p(1244)p(1244)p(1244)p(1244)p(1244)p(1244)p(1244)p)p(1244)p(1244)蜂群(羊群)下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个插座(1244)叉叉(1244)叉,下一个,下一个,下一个,下一个,下一个,下一个,下一个(1244)手,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,下一个,上| gethostbyaddr | pipe | stat | w | gethostbyname | pop | state | X | gethostent | pos | study | getlogin | print | substr z | getnetbyaddr | printf symlink abs | getnetbyname | prototype | ca |接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受方接受打平|休息|休息|恢复|打平|呼叫者|打平|重做|时间| chdir |打平|参考|次数|检查|(1244)uc;CH1244;CH1244;在在押服务人员姓名(1244)名称;更名;重命名;更名;更名;更名;更名;更名;更名;更名;更名;更名;截尾;截尾;截尾;截尾;截尾;截尾;截尾;截尾;截尾;截尾;截尾;截尾;在押;需求;需求;市政;uc;uc;uc;市政大学大学大学大学大学大学(1244)上述上述上述上述上述上述上述上述上述上述上述上述上述上述;市政,以及以及以及城市城市城市城市城市城市城市城市城市城市,城市城市,以及以及城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市,城市| grep | say | unshift | connect | hex | scalar | unte | cos | index | seek | use | crypt | INIT | seekdir | utime | dbmclose | int | select|(12)定义(12)加入(加入)加入(12)sem获取(12)等待(12)等待(12)删除(12)键(12)开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式开放式定义定义定义定义定义定义定义定义定义定义定义定义定义定义定义定义(定义定义定义(定义(定义)定义(定义)定义)定义:定义:加入加入加入加入加入加入加入(加入;加入;Se政政政政政政政政获取获取获取(12)学学学学学学获取(12))结束elsif | lt | qx | uuuuu文件| eq | m | s |线| exp | ne | sub | uuu包|用于| no | tr |和| foreach |或|除非| cmp | ge |包|继续||如果| qq | xor | do | le | qr | y | ARGV | STDERR | STDOUT | ARGVOUT | STDIN |;
而(){
打印“行=$”;
而(m{($singlequote_re)|($doublequote_re)|(\b$keywords_re\b)}g){
我的$singlequote=$1;
我的$doublequote=$2;
我的$keyword=$3;
如果(定义为$singlequote){
打印“单引号=\n”;
}elsif(定义为$doublequote){
打印“双引号=\n”;
}elsif(定义的$keyword){
打印“关键字=\n”;
}
}
}
__资料__
如果$string eq“time is eq”,则返回3+4;
产出:

Line = return 3 + 4 if $string eq "time is eq";
  Keyword = <return>
  Keyword = <if>
  Keyword = <eq>
  Double quote = <"time is eq">
Line=如果$string eq“time is eq”,则返回3+4;
关键字=
关键字=
关键字=
双引号=

注意,如果这不是一个练习,正确的建议是您使用,因为尝试用正则表达式解析perl是一种愚蠢的差事。总是会有边缘情况,所以使用实际的lexer是真正解决这个问题的唯一方法。

请提供一个字符串示例以及您想要提取的内容。您能给我们一个该表达式的示例吗Session?你为什么不提取
$string
+
3
4
,因为$string是一个变量,3和4是数字,+不是我要考虑的词。我有一个关键字列表,这就是为什么它是在一个变量中,然后请提供你想要黑名单的亲爱的,哇,真的好主意k你。我要试试这个它应该能用的!