我一直在用修饰符sm和g阅读perl正则表达式.我知道// g是一个全局匹配,它将是一个贪婪的搜索.
但我对修饰符s和m感到困惑.任何人都可以用代码示例解释s和m之间的区别,以显示它是如何不同的?我试图在线搜索,它只在http://perldoc.perl.org/perlre.html#Modifiers链接中给出了解释.在stackoverflow中,我甚至看到人们一起使用s和m.是不是s与m相反?
//s
//m
//g
Run Code Online (Sandbox Code Playgroud)
使用m我无法匹配多行.
use warnings;
use strict;
use 5.012;
my $file;
{
local $/ = undef;
$file = <DATA>;
};
my @strings = $file =~ /".*"/mg; #returns all except the last string across multiple lines
#/"String"/mg; tried with this as well and returns nothing except String
say for @strings;
__DATA__
"This is string"
"1!=2"
"This is \"string\""
"string1"."string2"
"String"
"S
t
r
i
n
g"
Run Code Online (Sandbox Code Playgroud)
Bor*_*din 14
您链接到自己的文档对我来说非常清楚.如果你能解释你对理解它有什么问题,以及你是如何思考这些问题/s并且/m是对立的,那将会有所帮助.
非常简单,/s改变点元字符的行为.,使其匹配任何字符.通常,它匹配任何东西,除了一个换行符"\n",所以将字符串作为S ^,即使它包含换行符英格尔线.
/m修改插入符^和美元$以便它们匹配于换行元字符内的字符串,将它作为米 ULTI行字符串.通常它们只匹配字符串的开头和结尾.
你不应该对/g修饰语"贪婪" 感到困惑.它适用于g lobal匹配,它将在字符串中找到所有出现的模式.术语贪婪通常是用户的量词的行为中的模式.例如.*,据说它是贪婪的,因为它将匹配尽可能多的字符,而不是.*?匹配尽可能少的字符.
更新
在修改后的问题,您正在使用/".*"/mg,其中/m,因为如上所指出,修改改变的唯一行为是无关紧要的$和^元字符,有没有在你的模式.
更改它/".*"/sg可以稍微改进一下,因为.现在可以匹配每行末尾的换行符,因此模式可以匹配多行字符串.(请注意,这里的对象字符串被认为是"单行" - 即匹配的行为就像在其中没有新行一样..)这里的Hower是贪婪的传统含义,因为pattern现在匹配从第一行中的第一个双引号到最后一行末尾的最后一个双引号的所有内容.我认为这不是你想要的.
有几种方法可以解决这个问题.我建议更改您的模式,以便您想要的字符串是双引号,后跟除双引号之外的任何字符序列,后跟另一个双引号.这是写的/"[^"]*"/g(请注意,/s修改器不再是必需的,因为模式中现在没有点)并且几乎完成了您想要的操作,除了转义的双引号被视为结束模式.
看看这个程序及其输出,注意我>>在每场比赛开始时都放了一个雪佛龙,这样就可以区分它们
use strict;
use warnings;
my $file = do {
local $/;
<DATA>;
};
my @strings = $file =~ /"[^"]*"/g;
print ">> $_\n\n", for @strings;
__DATA__
"This is string"
"1!=2"
"This is \"string\""
"string1"."string2"
"String"
"S
t
r
i
n
g"
Run Code Online (Sandbox Code Playgroud)
产量
>> "This is string"
>> "1!=2"
>> "This is \"
>> ""
>> "string1"
>> "string2"
>> "String"
>> "S
t
r
i
n
g"
Run Code Online (Sandbox Code Playgroud)
正如你可以看到现在一切都为了不同的是"This is \"string\""它已经找到两场比赛,"This is \"和"".修复可能比你想要的更复杂,但它是完全可能的.如果您需要修复,请说出来.
更新
我不妨完成这个.要忽略转义双引号并将其视为只是字符串的一部分,我们需要接受要么 \" 或者只是双引号的任意字符.这是使用正则表达式交替运算符完成的|,必须分组在非捕获括号内(?: ... ).最终结果是/"(?:\\"|[^"])*"/g(反斜杠本身必须被转义,因此它被加倍),当放入上面的程序时,产生这个输出,我认为是你想要的.
>> "This is string"
>> "1!=2"
>> "This is \"string\""
>> "string1"
>> "string2"
>> "String"
>> "S
t
r
i
n
g"
Run Code Online (Sandbox Code Playgroud)
/m并且/s都会影响匹配运算符处理多行字符串的方式.
使用/m修饰符,^并$匹配字符串中任何行的开头和结尾.如果没有/m修改,^而$只是匹配字符串的开头和结尾.
例:
$_ = "foo\nbar\n";
/foo$/, /^bar/ do not match
/foo$/m, /^bar/m match
Run Code Online (Sandbox Code Playgroud)
使用/s修饰符,特殊字符.匹配包括换行符在内的所有字符.如果没有/s修饰符,则.匹配除换行符之外的所有字符.
$_ = "cat\ndog\ngoldfish";
/cat.*fish/ does not match
/cat.*fish/s matches
Run Code Online (Sandbox Code Playgroud)
可以一起使用/sm修饰符.
$_ = "100\n101\n102\n103\n104\n105\n";
/^102.*104$/ does not match
/^102.*104$/s does not match
/^102.*104$/m does not match
/^102.*104$/sm matches
Run Code Online (Sandbox Code Playgroud)