如何用Perl的pos验证字符串指定区间匹配模式?修正#3正则
问题描述
实际需求:判断字符串中从位置7到15的字符是否全为1,示例代码如下:
my $str = "011000001111111111000011111110110111110000101010111"; my $i = 7, $j = 15; # 子串的起始和结束位置 my $l = $j - $i + 1; # 子串长度
尝试了三种验证方法:
# 1. 使用substr和正则 printf "#1: %d\n", substr($str,$i,$l) =~ /\A1*\Z/; # 2. 从字符串开头匹配的正则 printf "#2: %d\n", $str =~ /\A.{$i}1{$l}/; # 3. 使用pos和正则 pos($str) = $i; printf "#3: %d\n", $str =~ /1{$l}/;
预期所有结果都是0(false),但实际输出:
#1: 0 #2: 0 #3: 1
请问使用pos的情况下,#3的正确正则表达式是什么?
解决方案
问题原因
设置pos($str) = $i后,原正则/1{$l}/的逻辑是从pos指定位置往后查找存在连续$l个1的序列,而非强制要求从pos位置开始就必须是连续的$l个1。你的目标字符串中,pos=7的位置是字符0,但后续紧跟了多个连续1,因此正则跳过了开头的0,匹配到了后面的1序列,导致返回1。
正确写法
要确保从当前pos位置开始严格匹配连续的$l个1,需要使用\G锚定——它会强制匹配从当前pos位置(或上一次匹配结束位置)开始:
pos($str) = $i; printf "#3: %d\n", $str =~ /\G1{$l}/;
修改后,正则会检查pos=7位置开始的$l个字符是否全为1,由于该位置第一个字符是0,匹配失败,返回0,与前两种方法结果一致。
内容的提问来源于stack exchange,提问作者Fravadona
相关产品推荐
相关产品推荐

