我听说 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\/((.*?)\/[^\/]+).*\#
都失败了
您不认为转义会使正则表达式变得非常难以阅读吗?难道是我用错了什么?
您可以选择使用
!
而不是 /
来包围正则表达式,这样您就不必转义 /
。
m!//home/dev/((.*?)/[^/]+).*#!
应该可以。这是实际操作:http://ideone.com/TDrBG
您只需转义字符串本身中的特殊字符即可。 仅当您在字符串中查找特定字符时,才必须对正则表达式中的字符进行转义。 必须转义的特定字符在
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"