我有一段像这样的Perl代码(模式匹配),
$var = "<AT>this is an at command</AT>";
if ($var =~ /<AT>([\s\w]*)<\/AT>/i)
{
print "Matched in AT command\n";
print "$var\n\n";
}
如果标签之间的内容没有连字符,它可以正常工作。如果在像这样的标签之间的字符串之间插入连字符,则无法正常工作...... <AT>this is an at-command</AT>
。
即使连字符也被插入,任何人都可以修复此正则表达式吗?
帮帮我吧
塞特希
答案 0 :(得分:8)
您的模式包含此子模式:
[\s\w]*
[…]
是character class。像[aeiou]
这样的东西匹配任何一个小写元音。 [^…]
是否定的字符类。 [^aeiou]
与除了小写元音之外的任何内容匹配。
\s
是空白字符类的简写;单词字符类\w
。两者都不包含连字符。
*
是零或更多repetition说明符。
现在你应该理解为什么这个模式与连字符不匹配:它匹配零个或多个字符,它们是空格或字符。如果要匹配连字符,则可以将其包含在字符类中。
[\s\w-]*
例如,如果您还想要包含句号,问号和感叹号,那么您也可以简单地添加它们:
[\s\w.!?-]*
是有用的。它在字符类定义中用作正则表达式元字符来定义字符范围。例如,
[a-z]
匹配'a'
和'z'
之间范围内的任何字符之一。相比之下,
[az-]
匹配3个字符中的一个,'a'
,'z'
和'-'
。当您将-
作为字符类中的最后一个元素时,它将成为文字连字符而不是范围定义。您也可以将它作为第一个元素,或者将其转义(通过使用反斜杠,这也是您逃避所有其他正则表达式元字符的方式)。
即,以下3个字符类是相同的:
[az-] [-az] [a\-z]
答案 1 :(得分:4)
您可以在char类中添加连字符:
if ($var =~ /<AT>([\s\w-]*)<\/AT>/i)
此外,由于你的正则表达式中有/
,你可以使用不同的分隔符,这样就可以避免转义/
:
if ($var =~m{<AT>([\s\w-]*)</AT>}i)
答案 2 :(得分:2)
使用\ S而不是\ w。
if ($var =~ /<AT>([\s\S]*)<\/AT>/i) {
答案 3 :(得分:0)
如果你想要一切,你可以使用
if ($var =~ /<AT>((?:(?!<AT>).)*)<\/AT>/i)
这是不合适的。
答案 4 :(得分:0)
您需要为您的班级添加更多字符,例如[\ s \ w - ] *(正如codaddict告诉您的那样)。
此外,您应该使用lookahead来匹配命令的结尾(“我希望仅在匹配结束语句时才匹配”),如:
if ($var =~ /<AT>([^<]*)(?=<\/AT>)/i)
[^&lt;]代表“除”&lt;“之外的任何字符(包括连字符)。
你甚至可以添加一个lookbehind:
if ($var =~ (?<=/<AT>)([^<]*)(?=<\/AT>)/i)
对于更复杂的事情(因为你似乎想要一个小解析器),你应该看一下语法理论和lex / yacc。