由于存在大量对正则表达式引擎的黑客攻击,这可以通过现代正则表达式完成,但让我成为发布“不要使用正则表达式执行此操作”答案的人。
这不是正则表达式的工作。这是一个成熟的解析器的工作。作为一个你不能用(经典)正则表达式做的事情的例子,考虑一下:
()(())(()())
没有(经典)正则表达式可以确定这些括号是否正确匹配,但是没有正则表达式这样做是微不足道的:
/* C code */
char string[] = "()(())(()())";
int parens = 0;
for(char *tmp = string; tmp; tmp++)
{
if(*tmp == '(') parens++;
if(*tmp == ')') parens--;
}
if(parens > 0)
{
printf("%s too many open parenthesis.\n", parens);
}
else if(parens < 0)
{
printf("%s too many closing parenthesis.\n", -parens);
}
else
{
printf("Parenthesis match!\n");
}
# Perl code
my $string = "()(())(()())";
my $parens = 0;
for(split(//, $string)) {
$parens++ if $_ eq "(";
$parens-- if $_ eq ")";
}
die "Too many open parenthesis.\n" if $parens > 0;
die "Too many closing parenthesis.\n" if $parens < 0;
print "Parenthesis match!";
看看编写一些非正则表达式代码来为您完成这项工作是多么简单?
编辑:好的,从冒险乐园回来。 :) 试试这个(用 Perl 写的,如果你不了解 Perl,评论帮助你理解我在做什么):
# split $string into a list, split on the double quote character
my @temp = split(/"/, $string);
# iterate through a list of the number of elements in our list
for(0 .. $#temp) {
# skip odd-numbered elements - only process $list[0], $list[2], etc.
# the reason is that, if we split on "s, every other element is a string
next if $_ & 1;
if($temp[$_] =~ /regex/) {
# do stuff
}
}
另一种方法:
my $bool = 0;
my $str;
my $match;
# loop through the characters of a string
for(split(//, $string)) {
if($_ eq '"') {
$bool = !$bool;
if($bool) {
# regex time!
$match += $str =~ /regex/;
$str = "";
}
}
if(!$bool) {
# add the current character to our test string
$str .= $_;
}
}
# get trailing string match
$match += $str =~ /regex/;
(我给出两个是因为,在另一种语言中,一种解决方案可能比另一种更容易实施,而不仅仅是因为 There's More Than One Way To Do It™。)
当然,随着您的问题变得越来越复杂,构建一个成熟的解析器会带来一些好处,但那是另一回事。目前,这就足够了。