.NET正则表达式重叠匹配使用最后一个字符
我有一个正则表达式,它可以找到任何一个A,一个B和两个C的排列.NET正则表达式重叠匹配使用最后一个字符,.net,regex,.net,Regex,我有一个正则表达式,它可以找到任何一个A,一个B和两个C的排列 (?:(?<A>A)|(?<B>B)|(?<C>C)){4}(?<-A>)(?<-B>)(?<-C>){2} 如果我添加一个前瞻性断言,我可以计算从下一个位置开始而不是在完整序列后的下一个位置开始的重合数 (?=(?<value>(?:(?<A>A)|(?<B>B)|(?<C>C)){4}(?<-A>
(?:(?<A>A)|(?<B>B)|(?<C>C)){4}(?<-A>)(?<-B>)(?<-C>){2}
如果我添加一个前瞻性断言,我可以计算从下一个位置开始而不是在完整序列后的下一个位置开始的重合数
(?=(?<value>(?:(?<A>A)|(?<B>B)|(?<C>C)){4}(?<-A>)(?<-B>)(?<-C>){2}))
^ ^
正如斯特里比雪夫在前一篇文章中所帮助的那样:
现在我需要找到所有可能的组合的序列,例如,ABC,但3次,重叠一个字符
例如,对于以下序列:
AABCBACBCCAACCB
这将使序列处于位置1
Pos 1. ABC
Pos 3. CBA
Pos 5. ACB
因此,它看起来是一个序列,其中ABC的任意组合在一行中出现3次,但将前一个匹配的最后一个字符作为第一个字符
我希望我解释得很好
我如何才能做到这一点?您只需对解决方案进行简单修改即可实现这一点 首先,您只有
C
而不是两个:
(?:(?<A>A)|(?<B>B)|(?<C>C)){3}(?<-A>)(?<-B>)(?<-C>)
(?:(?A)|(?B)|(?C)){3}(?)(?)(?)
由于要从最后一个字符开始新的匹配,可以使用先行断言并仅捕获其后面的两个字符:
(?=(?:(?<A>A)|(?<B>B)|(?<C>C)){3}(?<-A>)(?<-B>)(?<-C>))..
(?=(?:(?A)|(?B)|(?C)){3}(?)(?)(?)。。
现在您只需重复三次,并只捕获最后一个角色:
(?:(?=(?:(?<A>A)|(?<B>B)|(?<C>C)){3}(?<-A>)(?<-B>)(?<-C>))..){3}.
(?:(?=(?:(?A)|(?B)|(?C)){3}(?)(?)(?)…{3}。
以下是如何在C#中实现这一点-请注意,s
变量将在整个过程中被修改,因此请先克隆它,或者使用副本:
var s = "AABCBACBCCAACCB AABCBACBCCAACCB AABBBAABCCAACCB";
var rx = new Regex("(?=(?<value>(?:(?<A>A)|(?<B>B)|(?<C>C)){3}(?<-A>)(?<-B>)(?<-C>)))");
var m = rx.Match(s);
while (m.Success)
{
var list = new List<string>();
list.Add(m.Groups["value"].Value);
s = s.Substring(m.Groups["value"].Index+m.Groups["value"].Length-1);
m = rx.Match(s);
if (m.Success && m.Groups["value"].Index == 0)
{
list.Add(m.Groups["value"].Value);
s = s.Substring(m.Groups["value"].Index+m.Groups["value"].Length-1);
m = rx.Match(s);
if (m.Success && m.Groups["value"].Index == 0)
{
list.Add(m.Groups["value"].Value);
Console.WriteLine(string.Join(", ", list));
s = s.Sustring(m.Groups["value"].Index+m.Groups["value"].Length-1);
m = rx.Match(s);
}
}
}
var s=“aabcbaccaaccab aabcbaccaaccab”;
var rx=new Regex(“(?=(?:(?)你需要用正则表达式来做这件事吗?即使有可能,我也怀疑迭代字符串并计算相关字符会更快更干净。@sln看起来像OP,最后一个例子是使用基于零的Pos
。@PetSerAl-没错,我是瞎了。如果只有2个呢?”几乎连续出现?你用什么语言写的?C#?只是正则表达式没有帮助。你需要职位详细信息吗?谢谢你的回答。我想我们已经接近了。我已经编辑了我的问题,因为我觉得我解释得不好。我想当你在模式中有4个字符时(比如ABCC),情况会类似或者4次重复而不是3次,但我无法计算出公式…@MikeJohnson假设你有REGEX
,它匹配四个字符,并且你想要四次重复:(?:(?=REGEX)。{3}{4}。
。第一次{}
将是字符数减去一,第二次{}
将是重复数。
(?:(?=(?:(?<A>A)|(?<B>B)|(?<C>C)){3}(?<-A>)(?<-B>)(?<-C>))..){3}.
var s = "AABCBACBCCAACCB AABCBACBCCAACCB AABBBAABCCAACCB";
var rx = new Regex("(?=(?<value>(?:(?<A>A)|(?<B>B)|(?<C>C)){3}(?<-A>)(?<-B>)(?<-C>)))");
var m = rx.Match(s);
while (m.Success)
{
var list = new List<string>();
list.Add(m.Groups["value"].Value);
s = s.Substring(m.Groups["value"].Index+m.Groups["value"].Length-1);
m = rx.Match(s);
if (m.Success && m.Groups["value"].Index == 0)
{
list.Add(m.Groups["value"].Value);
s = s.Substring(m.Groups["value"].Index+m.Groups["value"].Length-1);
m = rx.Match(s);
if (m.Success && m.Groups["value"].Index == 0)
{
list.Add(m.Groups["value"].Value);
Console.WriteLine(string.Join(", ", list));
s = s.Sustring(m.Groups["value"].Index+m.Groups["value"].Length-1);
m = rx.Match(s);
}
}
}