C# 如何使正则表达式匹配只添加一次到matches集合?

C# 如何使正则表达式匹配只添加一次到matches集合?,c#,regex,C#,Regex,我有一个字符串,其中有几个html注释。我需要计算表达式的唯一匹配项 例如,字符串可能是: var teststring = "<!--X1-->Hi<!--X1-->there<!--X2-->"; var teststring=“heree”; 我目前使用此选项获取匹配项: var regex = new Regex("<!--X.-->"); var matches = regex.Matches(teststring); var re

我有一个字符串,其中有几个html注释。我需要计算表达式的唯一匹配项

例如,字符串可能是:

var teststring = "<!--X1-->Hi<!--X1-->there<!--X2-->";
var teststring=“heree”;
我目前使用此选项获取匹配项:

var regex = new Regex("<!--X.-->");
var matches = regex.Matches(teststring);
var regex=new regex(“”);
var matches=regex.matches(teststring);
结果是3个匹配项。但是,我希望只有两个匹配,因为只有两个唯一的匹配

我知道我可能可以循环使用生成的MatchCollection并删除额外的匹配项,但我希望有一个更优雅的解决方案


澄清:示例字符串与实际使用的字符串相比大大简化。很容易就会有一个X8或X9,字符串中可能有几十个。提取注释并将其存储在数组中。然后可以过滤出唯一的值

但我不知道如何在C#中实现这一点。

我只会使用如下示例:

string subjectString = "<!--X1-->Hi<!--X1-->there<!--X2--><!--X1-->Hi<!--X1-->there<!--X2-->";
var regex = new Regex(@"<!--X\d-->");
var matches = regex.Matches(subjectString);
var uniqueMatches = matches
    .OfType<Match>()
    .Select(m => m.Value)
    .Distinct();

uniqueMatches.ToList().ForEach(Console.WriteLine);
 var distinctMatches = matchList.OfType<Match>().GroupBy(x => x.Value).Select(x =>x.First()).ToList();
string subjectString=“herehithere”;
var regex=新regex(@“”);
var matches=regex.matches(subjectString);
var uniqueMatches=匹配项
第()类
.选择(m=>m.Value)
.Distinct();
uniqueMatches.ToList().ForEach(Console.WriteLine);
输出如下:

<!--X1-->  
<!--X2-->


对于正则表达式,你可以用这个吗

(<!--X\d-->)(?!.*\1.*)
()(?!.*\1.*)
似乎在RegexBuddy中对测试字符串有效(至少=)

/()(?!.*\1.*)
// 
//选项:点匹配换行符
// 
//匹配下面的正则表达式,并将其匹配捕获到反向引用编号1«()»中
//按字面上的«-->»匹配字符“”
//断言不可能从该位置开始匹配下面的正则表达式(负前瞻)«(?。*\1.*»
//匹配任何单个字符«。*»
//在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)«*»
//通过捕获组号1«\1»匹配与最近匹配的相同文本
//匹配任何单个字符«。*»
//在零次和无限次之间,尽可能多次,根据需要回馈(贪婪)«*»

将注释的内部部分作为一个组捕获。然后将这些字符串放入哈希表(字典)。然后询问字典的计数,因为它会自动剔除重复

var teststring = "<!--X1-->Hi<!--X1-->there<!--X2-->";
var tokens = new Dicationary<string, string>();
Regex.Replace(teststring, @"<!--(.*)-->",   
     match => {  
     tokens[match.Groups[1].Value] = match.Groups[1].Valuel;  
     return ""; 
     });
var uniques = tokens.Keys.Count;
var teststring=“heree”;
var tokens=new Dicationary();
Regex.Replace(teststring,@“”,
匹配=>{
令牌[match.Groups[1].Value]=match.Groups[1].Valuel;
返回“”;
});
var uniques=tokens.Keys.Count;
通过使用Regex.Replace构造,可以在每次匹配时调用lambda。因为您对替换不感兴趣,所以不能将其设置为任何值

您必须使用组[1],因为组[0]是整个匹配项。
我只是在两边重复同样的内容,这样就更容易放入只存储唯一键的字典中。

取决于您可以使用的Xn数量:

(\<!--X1--\>){1}.*(\<!--X2--\>){1}

(\看来您正在做两件不同的事情:

  • 匹配的评论如//
  • 查找唯一注释集
  • 因此,将其作为两个不同的步骤来处理是相当合理的:

    var regex = new Regex("<!--X.-->");
    var matches = regex.Matches(teststring);
    
    var uniqueMatches = matches.Cast<Match>().Distinct(new MatchComparer());
    
    class MatchComparer : IEqualityComparer<Match>
    {
        public bool Equals(Match a, Match b)
        {
            return a.Value == b.Value;
        }
    
        public int GetHashCode(Match match)
        {
            return match.Value.GetHashCode();
        }
    }
    
    var regex=new regex(“”);
    var matches=regex.matches(teststring);
    var uniqueMatches=matches.Cast().Distinct(新的MatchComparer());
    类匹配比较器:IEqualityComparer
    {
    公共布尔等于(匹配a、匹配b)
    {
    返回a.值==b.值;
    }
    public int GetHashCode(匹配)
    {
    返回match.Value.GetHashCode();
    }
    }
    
    如果您希望在不转换为字符串的情况下从MatchCollection中获得一个不同的匹配列表,可以使用以下方法:

    string subjectString = "<!--X1-->Hi<!--X1-->there<!--X2--><!--X1-->Hi<!--X1-->there<!--X2-->";
    var regex = new Regex(@"<!--X\d-->");
    var matches = regex.Matches(subjectString);
    var uniqueMatches = matches
        .OfType<Match>()
        .Select(m => m.Value)
        .Distinct();
    
    uniqueMatches.ToList().ForEach(Console.WriteLine);
    
     var distinctMatches = matchList.OfType<Match>().GroupBy(x => x.Value).Select(x =>x.First()).ToList();
    
    var distinctMatches=matchList.OfType().GroupBy(x=>x.Value)。选择(x=>x.First()).ToList();
    

    我知道已经12年了,但有时我们需要这种解决方案,所以我想与大家分享.C#evolved、.NET evolved,所以现在更容易了。

    我喜欢这个想法,但不幸的是结果不是预期的。在我的单元测试中(有更大的字符串)当我应该收到4个结果时,我得到了8个结果。不确定RegexBuddy和我正在使用的结果之间的区别是什么。(另外,我尝试使用Distinct()但是MatchCollection,即使它是从IEnumerable派生的,似乎也无法识别这一点。您的字符串要大得多吗?在MatchCollection上,您很可能必须使用var stuff=theMatchCollection.OfType().Select(m=>m.Value).Distinct(),或其他。不可能将其粘贴到此处…通常会生成4k html文件。我正在查看不同的更多。越来越近…当前版本看起来与上面的类型相似。:)Linq和Lambdas对我来说还是有点陌生。太棒了!回答得太好了…我自己花了30分钟才弄明白那个修改过的例子。你测试过这个吗?出于某种原因,我无法弄清楚()使用MatchCollection,即使这是包含它的第二个答案。我正在使用.NET3.5,并且在我的using语句中使用System.Linq。您应该使用OfType,而不是CAST。我希望确保在出现匹配以外的任何内容时,它会引发异常。OfType将继续并忽略可能不匹配的内容,这可能会隐藏参考底图解决问题。