获得所有匹配的正则表达式是什么:
IF(.....);
我需要获取上一个字符串的开头和结尾:内容也可以是(
和)
,然后可以是其他(... IF (...) ....)
我只需要 IF 内的内容。
有什么想法吗?
那是因为,我需要得到一个Excel公式(如果条件)并将其转换为另一种语言(java脚本)。
修改
我试过了
`/IF\s*(\(\s*.+?\s*\))/i or /IF(\(.+?\))/`
这不起作用,因为只有在)
(
或'IF(...)'
时才匹配
答案 0 :(得分:3)
我怀疑你有一个不适合正则表达式匹配的问题。你想做无限计数(所以你可以匹配开括号和右括号),这不仅仅是正则表达式可以处理的。但是,手动滚动解析器以进行所需的匹配应该不会很难。
基本上(伪代码):
Find "IF"
Ensure next character is "("
Initialise counter parendepth to 1
While parendepth > 0:
place next character in ch
if ch == "(":
parendepth += 1
if ch == ")":
parendepth -= 1
添加少量“记住开始”和“记住结束”,你应该全部设定。
答案 1 :(得分:1)
这是Perl中的一种方法。任何允许递归的正则表达式
应具备这种能力。
在这个例子中,正确的括号被注释的事实
(见输出)和平衡,意味着它可以存储数据
以结构化的方式
这绝不会验证任何东西,它只是一个快速的解决方案。
use strict;
use warnings;
##
$/ = undef;
my $str = <DATA>;
my ($lvl, $keyword) = ( 0, '(?:IF|ELSIF)' ); # One or more keywords
# (using 2 in this example)
my $kwrx = qr/
(\b $keyword \s*) #1 - keword capture group
( #2 - recursion group
\( # literal '('
( #3 - content capture group
(?:
(?> [^()]+ ) # any non parenth char
| (?2) # or, recurse group 2
)*
)
\) # literal ')'
)
| ( (?:(?!\b $keyword \s*).)+ ) #4
| ($keyword) #5
/sx;
##
print "\n$str\n- - -\n";
findKeywords ( $str );
exit 0;
##
sub findKeywords
{
my ($str) = @_;
while ($str =~ /$kwrx/g)
{
# Process keyword(s), recurse its contents
if (defined $2) {
print "${1}[";
$lvl++;
findKeywords ( $3 );
}
# Process non-keyword text
elsif (defined $4) {
print "$4";
}
elsif (defined $5) {
print "$5";
}
}
if ($lvl > 0) {
print ']';
$lvl--;
}
}
__DATA__
IF( some junk IF (inner meter(s)) )
THEN {
IF ( its in
here
( IF (a=5)
ELSIF
( b=5
and IF( a=4 or
IF(its Monday) and there are
IF( ('lots') IF( ('of') IF( ('these') ) ) )
)
)
)
then its ok
)
ELSIF ( or here() )
ELSE (or nothing)
}
输出:
IF( some junk IF (inner meter(s)) )
THEN {
IF ( its in
here
( IF (a=5)
ELSIF
( b=5
and IF( a=4 or
IF(its Monday) and there are
IF( ('lots') IF( ('of') IF( ('these') ) ) )
)
)
)
then its ok
)
ELSIF ( or here() )
ELSE (or nothing)
}
- - -
IF[ some junk IF [inner meter(s)] ]
THEN {
IF [ its in
here
( IF [a=5]
ELSIF
[ b=5
and IF[ a=4 or
IF[its Monday] and there are
IF[ ('lots') IF[ ('of') IF[ ('these') ] ] ]
]
]
)
then its ok
]
ELSIF [ or here() ]
ELSE (or nothing)
}
答案 2 :(得分:0)
这应该可以工作并捕获括号中的所有文本,包括括号,作为第一个匹配:
/IF(\(.+?\))/
请注意,它与IF()
(空括号)不匹配:如果您还要匹配空括号,则可以将+
(匹配一个或多个)替换为{{1 (匹配零或更多):
*
---编辑
如果您需要将公式与括号匹配(除了最外面的公式),您可以使用
/IF(\(.*?\))/
这将通过删除 /IF(\(.*\))/
使正则表达式“不贪婪”。这样它将匹配可能的最长字符串。对不起,我错误地认为你没有任何副括号。
答案 3 :(得分:0)
扩展Paolo的答案,您可能还需要担心空格和案例:
/IF\s*(\(\s*.+?\s*\))/i
答案 4 :(得分:0)
不可能只使用正则表达式。如果您是或可以使用.NET,您应该使用Balanced Matching。