Regex 如何有效地匹配Perl正则表达式中已经匹配的内容?
我编写了一个正则表达式来验证必须遵守以下规则的字符串:Regex 如何有效地匹配Perl正则表达式中已经匹配的内容?,regex,perl,lookahead,lookaround,Regex,Perl,Lookahead,Lookaround,我编写了一个正则表达式来验证必须遵守以下规则的字符串: 必须至少包含一个字符 必须不包含空白字符 第一个字符不能是标点符号 最后一个字母可能不是标点符号 不能以标点符号后跟数字结尾 所有其他字符可以是除/[:@#]以外的任何UTF-8字符 以下是正则表达式: my $name_re = qr/ [^[:punct:][:blank:]] # not punct or blank (?: # followed by..
/[:@#]
以外的任何UTF-8字符my $name_re = qr/
[^[:punct:][:blank:]] # not punct or blank
(?: # followed by...
[^[:blank:]:@#]* # any number non-blank, non-@, non-#, non-@
[^[:punct:][:blank:]] # one not blank or punct
)? # ... optionally
/x;
看到少了什么吗?规则#5不强制执行。我一直在通过编写如下代码来实现它:
die "$proj is not a valid name" unless $proj =~ /\A$name_re\z/
&& $proj !~ /[[:punct:]][[:digit:]]+\z/;
有很多地方我必须这样做,所以我宁愿所有的事情都在一个正则表达式中完成。问题是:怎么做?哪个正则表达式会拒绝诸如“foo,23”之类的值?
my $name_re = qr/
\A(?![[:punct:]]) # first character isn't punctuation
(?: # start non-capturing group, repeated once or more
(?![[:punct:]][[:digit:]]+\z) # make sure 5th condition isn't violated
[^[:blank:]:@#] # match a valid character
)+ # end non-capturing group
(?<![[:punct:]])\z # last character isn't punctuation
/x;
my$name\u re=qr/
\第一个字符不是标点符号
(?:#启动非捕获组,重复一次或多次
(?![[:punct:][[:digit:][]+\z)#确保没有违反第5个条件
[^[:blank::@#]#匹配有效字符
)+#结束非捕获组
(?
如果您可以使用可变长度的lookbehind,这将更简单,但我认为Perl不支持它们。@f-j的答案对于匹配完整字符串是正确的,但是还需要一个变量,该变量可以作为较大字符串的一部分与其中的其他内容匹配。以下是该版本:
my $name_re = qr/
(?![[:punct:]]) # first character isn't punctuation
(?: # start non-capturing group, repeated once or more ...
(?! # negative look ahead for...
[[:punct:]] # punctuation
[[:digit:]]+ # digits
(?:$|[[:blank:]]) # eol or blank
) # ...
[^[:blank:]:@#] # match a valid character
)+ # ... end non-capturing group
(?<![[:punct:]])\b # last character isn't punctuation
/x;
my$name\u re=qr/
(?![:punct:])#第一个字符不是标点符号
(?:#启动非捕获组,重复一次或多次。。。
(?!#消极展望。。。
[:点状:]#标点符号
[[:位:]+#位
(?:$|[:blank:])#下线或空白
) # ...
[^[:blank::@#]#匹配有效字符
)+#…结束非捕获组
(?这并不禁止以标点符号加上任何数字结尾的字符串,即/[:punct:][:digit:]*/
。并且向后看的字符串必须是固定宽度的,因此不能使用*
。:-(这会发出“有效”,但应该发出“无效”:perl-E'say“foo,23”=~/\a(?![:punct:])(?:(?:(!![:punct:]\d+$)[^[:blank::])+(?@theory-我的“后视”没有重复,我做了一些小的编辑,但它总是检查结尾的标点和数字(我只将\d
切换到[:digit://code>,并将“前视”中的$
更改为\z
)@theory-抱歉,我对POSIX字符类的工作方式有点不熟悉,我认为在从[:punct:][/code>切换到[:punct:][/code>和其他类似更改后,它现在应该可以正常工作了。是的,这会发出“无效的”:perl-E'说“foo,23”=~/\a(?[:punct:][digit:][digit:][digit:][digit:][+\z][^[:blank::][+(?