我有一个字符串,该字符串可以有两种形式,但每次都用哪种形式是未知的:
hello world[0:10];
或hello world;
可能带有或没有带有数字的方括号。两个词(hello和world)可以不同。如果有括号和数字,则第一个数字始终为0,第二个数字(10)有所不同。
我需要捕获第一个单词(你好),如果有,请捕获第二个数字(10)。我还需要知道它是哪种形式的字符串。
hello world[0:10];
我将捕获{hello,10,form1},而hello world;
我将捕获{hello,form2}。我并不在乎“表单”的格式,我只需要能够区分即可。可以是一点(1 = form1、0 = form2),结构(form1将我置于一个范围内,而form2将我置于另一个范围内)等等。
我目前有以下(正在运行)正则表达式:
/(\w*) \s \w* (?:\[0:(\d*)\])?;/x
这给了我$1 = hello
并可能给我$2 = 10
。 我现在只需要知道方括号中的数字是否存在。这将重复很多次,所以我不能假设 $2 = undef
进入正则表达式。 $2
也可能连续几遍是同一件事,所以我不能只是在正则表达式前后查找$2
中的变化。
到目前为止,我最好的解决方案是两次运行该正则表达式,第一次使用方括号,第二次不使用方括号:
if( /(\w*) \s \w* \[0:(\d*)\];/x ) {...}
elsif( /(\w*) \s \w*;/x ) {...}
这似乎效率很低而且很不优雅,所以我想知道是否有更好的方法?
答案 0 :(得分:4)
您可以使用?
来匹配正则表达式的各个部分。然后,您可以将输出直接捕获为正则表达式的返回值。
my $re = qr{ (\w*) \s* (?:\[0:(\d+)\])?; }x;
if( my($word, $num) = $line =~ $re ) {
say "Word: $word";
say "Num: $num" if defined $num;
}
else {
say "No match";
}
(?:\[0:(\d+)\])?
说可能是[0:\d+]
。 (?:)
使分组无法捕获,因此仅捕获了\d+
。
$1
和$2
也是安全使用的,它们在每次匹配时都会重置,但是使用词法变量会使情况更明确。