我的字符串是
$s = "AAATAATAGCAV";
模式1
$s =~m/AT?.?A/g;
此处T?
无法搜索。 .?
匹配字符串第二个字符(A A A),最后A
匹配(AA A )
模式2
$s =~m/A.?T?A/g
.?
匹配第二个字符。 T?
无法搜索。结果相同
这是我的疑问
$s =~m/A.?T?AA/
从头开始A
匹配字符串
.?
匹配任何一个字符匹配或不匹配字符串。所以它匹配第二个字符作为模式1和模式2.
T?
也匹配任何一个字符匹配或不匹配字符串。
AA
匹配字符串中的AA
字符。
为什么以上模式不会与AATAA
或ATAA
匹配。搜索引擎如何运作。为什么结果为AAA
答案 0 :(得分:2)
有一种很简单的方法可以看出正则表达式在做什么:
use re 'debug';
E.g:
#!/usr/bin/env perl
use strict;
use warnings;
use re 'debug';
my $str = 'AAATAATAGCAV';
$str =~m/A.?T?AA/;
这将打印:
Compiling REx "A.?T?AA"
Final program:
1: EXACT <A> (3)
3: CURLY {0,1} (6)
5: REG_ANY (0)
6: CURLY {0,1} (10)
8: EXACT <T> (0)
10: EXACT <AA> (12)
12: END (0)
anchored "A" at 0 floating "AA" at 1..3 (checking floating) minlen 3
Matching REx "A.?T?AA" against "AAATAATAGCAV"
Intuit: trying to determine minimum start position...
doing 'check' fbm scan, [1..12] gave 1
Found floating substr "AA" at offset 1 (rx_origin now 0)...
doing 'other' fbm scan, [0..1] gave 0
Found anchored substr "A" at offset 0 (rx_origin now 0)...
(multiline anchor test skipped)
Intuit: Successfully guessed: match at offset 0
0 <> <AAATAATAGC> | 1:EXACT <A>(3)
1 <A> <AATAATAGCA> | 3:CURLY {0,1}(6)
REG_ANY can match 1 times out of 1...
2 <AA> <ATAATAGCAV> | 6: CURLY {0,1}(10)
EXACT <T> can match 0 times out of 1...
2 <AA> <ATAATAGCAV> | 10: EXACT <AA>(12)
failed...
failed...
1 <A> <AATAATAGCA> | 6: CURLY {0,1}(10)
EXACT <T> can match 0 times out of 1...
1 <A> <AATAATAGCA> | 10: EXACT <AA>(12)
3 <AAA> <TAATAGCAV> | 12: END(0)
Match successful!
Freeing REx: "A.?T?AA"
所以回答你的问题 - 这在开始时与AAA
匹配 - 因为你有一个可选的(.?
),这意味着零有效。还有一个可选的T?
,这意味着没有一个在那里也是有效的。
因此,第一个子字符串与您的目标模式匹配。通过这样做(默认情况下!)消耗该模式的一部分,使其无法再与之匹配。所以拿你的第一个例子:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
use re 'debug';
my $s = 'AAATAATAGCAV';
my @matches = $s =~m/(AT?.?A)/g;
print Dumper \@matches;
给出:
$VAR1 = [
'AAA',
'AA'
];
这会将第一个匹配项设为AAA
,将第二个匹配项设置为字符串AA
。(AAA)T(AA)TAGCAV
。由于子字符串已匹配,因此模式匹配引擎不再“可用”。如果你真的需要,你可以做到这一点,但是如果你要走下去,我建议你努力思考你正在尝试用你的正则表达式做什么。但您可以使用"look around"匹配。
另外:通常使用单个char变量名称的形式非常糟糕。称之为描述性的东西。
答案 1 :(得分:2)
我在正则表达式中添加了一个嵌入代码,以查看引擎在搜索时的位置。这里的关键是理解“碰撞”。
匹配完成后,下一场可能的匹配只能在上一场比赛结束后开始。
my $s = "AAATAATAGCAV";
my $n = 1;
while($s =~
m/
# Embedded code construct (?{ })
(?{print "\n", $n++, ". Starting match at: [$`||$']: "})
# Same as AT?.?A
A T? .? A
/gx
){
print "Found: [$&]";
}
1. Starting match at: [||AAATAATAGCAV]: Found: [AAA]
2. Starting match at: [AAAT||AATAGCAV]: Found: [AA]
3. Starting match at: [AAATAAT||AGCAV]:
4. Starting match at: [AAATAATAGC||AV]:
在以下地点开始比赛:[|| AAATAATAGCAV]:发现:[AAA]
以上是上述步骤的进展情况:
答案 2 :(得分:1)
Regex: A.?T?AA
Text: AAATAATAGCAV
正则表达式将从文本中的第一个字符开始匹配,并查看是否有任何方式匹配该模式。此外,?
是贪婪的,所以它首先尝试匹配1个字符,如果失败,它将匹配0个字符。让我们看看这是如何转化为比赛的每一步:
Pattern: A.TAA
Text: AAATAATAGCAV
| Failed
The pattern failed while matching 'T' from 'T?', so now try to match 0 characters there.
Pattern: A.AA
Text: AAATAATAGCAV
| Failed
The pattern failed while matching the last 'A'. There's one more pattern now before moving on to the next character - the one where .? matches 0 characters.
Pattern: AAA
Text: AAATAATAGCAV
Success!