perl 正则表达式转义字符

问题描述 投票:0回答:3

我听说 Perl 是一种很好的正则表达式语言,但我对需要转义的字符有点困惑

我在http://regexlib.com/RETester.aspx上测试了代码并得到了我想要的结果

//home/dev/abc/code/hello/world.cpp#1
//home/dev/((.*?)/[^/]+).*#

Match   $1  $2
//home/dev/abc/code/hello/world.cpp#    abc/code    abc

但是,我不太确定如何将其转换为 Perl 代码

我试过了,

\/\/home\/dev\/\(\(\.\*\?\)\/\[\^\/\]\+\)\.\*\#

\/\/home\/dev\/((.*?)\/[^\/]+).*\#

都失败了

您不认为转义会使正则表达式变得非常难以阅读吗?难道是我用错了什么?

regex perl
3个回答
10
投票

如果您使用 Perl,则不必使用

/
作为正则表达式分隔符,如果您在分隔符前面添加“m”作为匹配运算符,或使用“s”作为替换运算符(例如,您可以使用
# 
!
甚至任何平衡的括号/方括号:
s[this][that]
),然后你就不必转义
/
。您还可以使用 quotemeta 函数或
\Q
\E
正则表达式 转义序列 自动转义任何元字符。


6
投票

您可以选择使用

!
而不是
/
来包围正则表达式,这样您就不必转义
/

m!//home/dev/((.*?)/[^/]+).*#!

应该可以。这是实际操作:http://ideone.com/TDrBG


0
投票

您只需转义字符串本身中的特殊字符即可。 仅当您在字符串中查找特定字符时,才必须对正则表达式中的字符进行转义。 必须转义的特定字符在

perldoc -f quotemeta
中列出,如下
\ | ( ) [ { ^ $ * + ? .

正如前面的答案所说,如果您使用正斜杠作为正则表达式分隔符,则必须转义正斜杠

/
。 因为
/
是普通的正则表达式分隔符,所以如果您要在字符串中查找
/
字符,则必须对其进行转义。 或者,您可以使用不同的分隔符。 在我的代码中我只是逃避了它。

我将

.*?
更改为
.+?
,因为目录路径不能为空,必须有一些东西。 另外,我没有使用
[^/]+
,而是将其更改为上一场比赛的副本,末尾带有
/
,即
.+?/

它们基本上是做同一件事的两种略有不同的方法。 此外,当字符串被像

/
这样的字符分割时,在该字符上分割字符串可能会更容易。 我在下面的代码中展示了这两种方法。

#!/usr/bin/perl -w

my $s = "//home/dev/abc/code/hello/world.cpp";

if( $s=~/\/\/home\/dev\/((.+?)\/.+?)\// ){
  print "Original string:\t$s\n";
  print "Matched:\t\t$&\n";  #$& is a special variable to show what was matched
  print "Backreference 1:\t$1\n";
  print "Backreference 2:\t$2\n";
}

print "-----\n";
print "Sometimes it is easier to split the string on the / character\n";
my @directoryNames = split(/\/+/, $s); #split on one or more foward slashes

for( @directoryNames ){
  print "\"$_\"\n";
}

print "The first value is empty because of the leading //\n";
print "The specific path you wanted is \"$directoryNames[3]/$directoryNames[4]\" \"$directoryNames[4]\"\n";

输出看起来像这样

$ perl dirPath.pl
Original string:    //home/dev/abc/code/hello/world.cpp
Matched:            //home/dev/abc/code/
Backreference 1:    abc/code
Backreference 2:    abc
-----
Sometimes it is easier to split the string on the / character
""
"home"
"dev"
"abc"
"code"
"hello"
"world.cpp"
The first value is empty because of the leading //
The specific path you wanted is "abc/code" "code"
© www.soinside.com 2019 - 2024. All rights reserved.