Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以精确偏移量匹配正则表达式_C#_.net_Regex - Fatal编程技术网

C# 以精确偏移量匹配正则表达式

C# 以精确偏移量匹配正则表达式,c#,.net,regex,C#,.net,Regex,我想检查某个模式(如双引号字符串)是否与某个精确位置匹配 示例 string text = "aaabbb"; Regex regex = new Regex("b+"); // Now match regex at exactly char 3 (offset) of text 我想检查regex是否正好与char 3匹配。 我查看了Regex.Match方法(String,Int32),但它的行为与我预期的不同。 所以我做了一些测试和解决办法: public void RegexTest2

我想检查某个模式(如双引号字符串)是否与某个精确位置匹配

示例

string text = "aaabbb";
Regex regex = new Regex("b+");
// Now match regex at exactly char 3 (offset) of text
我想检查
regex
是否正好与char 3匹配。
我查看了
Regex.Match方法(String,Int32)
,但它的行为与我预期的不同。
所以我做了一些测试和解决办法:

public void RegexTest2()
{
    Match m;
    string text = "aaabbb";
    int offset = 3;

    m = new Regex("^a+").Match(text, 0); // lets do a sanity check first
    Assert.AreEqual(true, m.Success);
    Assert.AreEqual("aaa", m.Value);  // works as expected

    m = new Regex("^b+").Match(text, offset);
    Assert.AreEqual(false, m.Success);  // this is quite strange...

    m = new Regex("^.{"+offset+"}(b+)").Match(text); // works, but is not very 'nice'
    Assert.AreEqual(true, m.Success);
    Assert.AreEqual("bbb", m.Groups[1].Value);

    m = new Regex("^b+").Match(text.Substring(offset)); // works too, but 
    Assert.AreEqual(true, m.Success);
    Assert.AreEqual("bbb", m.Value);
}
事实上,我开始相信
newregex(“^.”,1).Match(myString)
永远不会匹配任何东西

有什么建议吗

编辑:


我得到了一个有效的解决方案(变通办法)。所以我的问题是关于速度和一个好的实现。

你可以添加一个积极的lookback断言(
(?你试过了吗

如果你想限制比赛,那么 它从一个特定的地方开始 字符串中的字符位置和 正则表达式引擎不支持 扫描字符串的其余部分以查找 匹配,锚定正则表达式 带有一个\G(在左边表示一个 从左到右的模式,或在右侧 对于从右到左的模式) 限制匹配,因此它必须开始 正是在startat

i、 e.将
^
替换为
\G

m = new Regex(@"\\Gb+").Match(text, offset);
Assert.AreEqual(true, m.Success);  // should now work
您希望
匹配(文本,偏移量)
开始计算搜索的字符串,就像它从偏移量开始一样。事实并非如此。
^
将实际计算为偏移量
0
,而不是
偏移量

因此,使用将计算
^
偏移量的:

m = new Regex("^bbb$").Match(text, offset, text.Length-offset);
另一种选择是使用,但速度比上面的慢:

m = new Regex("^.{"+offset+"}bbb$").Match(text);
或者这样(第一种方法最快):


抱歉,我忘了提一下,“3”的偏移量是一个变量。如果我为每个调用构建一个新的正则表达式,会不会显著降低性能?那么,在这种情况下,我建议使用
子字符串
,首先获取字符串的相关部分,然后在其余部分释放正则表达式的愤怒。如果要匹配字符串,不是很慢吗ed on很长?比我快8秒,我花了太长时间确认
:P
\G
在这里是正确的,但我会添加一个关于使用相同
Regex
对象的警告,假设OP不会每次创建一个新对象。我不太确定它会如何运行,但它可能会记住最后一个位置,即使有偏移量。我值得检查一下。(同样,我也不确定)@Kobi-我怀疑只有在使用m.MatchNext()时才会出现这种情况,而不是在同一个正则表达式对象上再次调用Match()。@CAFxX:它应该是
@“\Gb+”
“\\Gb+”
。我确实读过:
比赛必须在上一场比赛结束时进行。
这并没有说服我去尝试。非常感谢!
m = new Regex("^bbb$").Match(text, offset, text.Length-offset);
m = new Regex("^.{"+offset+"}bbb$").Match(text);
m = new Regex(@"\Gbbb$").Match(text, offset);