RegexSpilt基于C#中的多个分隔符

本文关键字:分隔符 基于 RegexSpilt | 更新日期: 2023-09-27 18:21:41

我有一个类型为"KeyOperatorValue1,Value2,Value2...."的字符串。例如="version>=5""lang=en,fr,es"等,当前运算符字段的可能值为"=", "!=", ">", ">=", "<", "<=",但我不希望仅限于它们。现在问题是给定这样一个字符串,我怎么能分裂成三元组?

由于所有运算符的字符串表示都不是互斥的("="">="的子集),所以我不能使用public string[] Split(string[] separator, StringSplitOptions options)Regex.Split也没有以多个正则表达式作为参数的变体。

RegexSpilt基于C#中的多个分隔符

由于您没有提到输入的格式,我做了一些假设。。

我假设

  • 键总是包含字母数字字符
  • 值将始终是字母数字字符
  • 键值对将由非单词字符分隔

    (?<key>'w+)(?<operand>[^'w,]+)(?<value>['w,]+)
    

因此,如果字符串不是,[a-zA-Z'd_] 中的任何一个,则这将匹配作为操作数的字符串


你可以使用这个代码

var lst=Regex.Matches(input,regex)
             .Cast<Match>()
             .Select(x=>new{
                   key=x.Groups["key"].Value,
                   operand=x.Groups["operand"].Value,
                   value=x.Groups["value"].Value
                   });

您现在可以在第一个上迭代

foreach(var l in lst)
{
    l.key;
    l.operand;
    l.value;
}

Regex有"or"运算符(不过结果中会包含分隔符):

Regex.Split(@sourceString, @"(>=)|(<=)|(!=)|(=)|(>)|(<)");

您不必使用正则表达式来实现这一点。只需将运算符存储在一个数组中。保持数组按运算符的长度排序。对运算符进行迭代,并使用IndexOf()获得运算符的位置。现在可以使用Substring()从输入字符串中提取键和值。

您可以使用分支来提供多个备选方案。实现这一点有多种可能性,一个例子是:

('w+)([!<>]?=|[<>])(.*)

正如您所看到的,这个表达式包含三个独立的捕获组:

  • ('w+?):这将匹配"单词"字符(字母数字和下划线),只要序列至少有一个字符长(+
  • ([!<>]?=|[<>]):这个表达式与示例中给出的运算符相匹配。前半部分([!<>]?=)将匹配[]内的任何字符(或跳过它(?)),然后是=。备选方案仅匹配<>
  • (.*):这将匹配任何字符(或不匹配任何字符),无论后面是什么,直到字符串/行结束

因此,当你匹配表达式时,你会得到总共4个(子)匹配:

  • 1:密钥的名称
  • 2:使用的运算符
  • 3:给出的实际值

编辑:如果你也想匹配其他操作符,你必须将它们添加为第二个匹配组中的额外分支:

('w+)([!<>]?=|[<>]|HERE)(.*)

请记住,在不定义应被视为有效操作数(或操作数的组成部分)的确切字符的情况下,通常没有100%完美的方法来匹配任何运算符。