Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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 正则表达式匹配perl变量_Regex_Perl_Variables - Fatal编程技术网

Regex 正则表达式匹配perl变量

Regex 正则表达式匹配perl变量,regex,perl,variables,Regex,Perl,Variables,我目前正在学习正则表达式,并尝试创建一个正则表达式来匹配Perl中的任何合法变量名 这是我到目前为止写的: ^\$[A-Za-z_][a-zA-Z0-9_]* 唯一的问题是正则表达式对于特殊符号返回true,例如字符串$a&将返回true 我做错了什么 谢谢! Rotem最后需要一个$,否则它只会尽可能匹配,而忽略其余部分。因此,它应该是: ^\$[A-Za-z_][A-Za-z0-9]*$ 解析Perl很困难,什么是变量和什么不是变量的规则也很复杂。如果您试图解析Perl,请考虑使用。它可

我目前正在学习正则表达式,并尝试创建一个正则表达式来匹配Perl中的任何合法变量名

这是我到目前为止写的:

^\$[A-Za-z_][a-zA-Z0-9_]*
唯一的问题是正则表达式对于特殊符号返回true,例如字符串$a&将返回true

我做错了什么

谢谢!
Rotem

最后需要一个
$
,否则它只会尽可能匹配,而忽略其余部分。因此,它应该是:

^\$[A-Za-z_][A-Za-z0-9]*$

解析Perl很困难,什么是变量和什么不是变量的规则也很复杂。如果您试图解析Perl,请考虑使用。它可以解析Perl程序,并执行查找所有变量之类的操作。PPI是用来完成其工作的

如果你想试着去做它,这里有一些要考虑的边缘情况……/P>

$^F
$/
${^ENCODING}
$1
$élite           # with utf8 on
${foo}
*{foo} = \42;
*{$name} = \42;  # with strict off
${$name} = 42;   # with strict off
当然还有其他信号
@%*
。以及检测单个带引号的字符串中是否有内容。这是我强烈鼓励你使用PPI而不是自己尝试的方式

如果你想练习,现实的做法是从更大的字符串中提取变量,而不是进行精确匹配

# Match the various sigils.
my $sigils         = qr{ [\$\@\%*] }x;

# Match $1 and @1 and so on
my $digit_var      = qr{ $sigils \d+ }x;

# Match normal variables
my $named_var      = qr{ $sigils [\w^0-9] \w* }x;

# Combine all the various variable matches
my $match_variable = qr{ ( $named_var | $digit_var ) }x;

这将使用
()
捕获操作符仅获取变量。它还使用
/x
修饰符使正则表达式更易于阅读,并避免使用其他分隔符。使用
\w
而不是
A-Z
可确保启用时拾取Unicode字符,禁用时不会拾取。最后,
qr
被用来构建分段的正则表达式。填补空白只是一个练习。

我需要解决这个问题来创建一个简单的源代码分析器。
此子例程从代码的输入部分提取Perl用户变量

sub extractVars {
    my $line = shift;
    chomp $line;
    $line =~ s/#.*//;       # Remove comments
    $line =~ s/\s*;\s*$//;  # Remove trailing ;
    my @vars = ();
    my $match = 'junk';
    while ($match ne '') {
        push @vars, $match if $match ne 'junk';
        $match = ''; 
        if ($line =~ s/(
                [\@\$\%]            # $@%
                {?                  # optional brace
                \$?                 # optional $
                [\w^0-9]            # begin var name
                [\w\-\>\${}\[\]'"]* # var name
                [\w}\]]             # end var name
                |
                [\@\$\%]            # $@%
                {?                  # optional brace
                \$?                 # optional $
                [\w^0-9]            # one letter var name
                [}\]]?              # optional brace or bracket
                )//x) {
            $match = $1;
            next;
        }
    }
    return @vars;
}
使用以下代码对其进行测试:

my@variables=extractVars('$a$a{b}$a[c]$scalar@list%hash$list[0][1]$list[-1]$hash{foo}{bar}$aref->{foo}$href->{foo}->{bar}$$aref%$hash_ref%{$aref->{foo}$hash{foo}}$a'$var{abc})

如果变量名包含空格,则不起作用,例如:

  • $hash{“baz-qux”}
  • ${$var->{foo}}[0]

将匹配仅包含变量的字符串。它与包含变量的字符串不匹配。看起来这正是他想要的。否则,对于
$a&
,它为true是正确的,因为这只是一个后跟
&
运算符的变量。但请注意,他的正则表达式以
^
开头,因此他希望变量位于开头。这与
$17
$lite
不匹配,这两个变量在Perl中都是合法的变量名。@Rotem
“foo”=~(o+);打印$1@12 = (1..10); 打印$12[7]$foo::bar
,或者
%:
。我不打算使用我的正则表达式。我正在学习如何编写它们,我认为变量名是一个很好的实践,仅此而已:)谢谢!对不起,我不知道这只是个练习。在这种情况下,我已经更新了一个良好的开端,告诉您如何解决这个问题。