从字符串中获取参数

时间:2019-04-03 15:54:11

标签: c# c#-4.0

有没有一种简单的方法来检查2个字符串是否包含相同的参数?

示例:

  • ReferenceString =“某物{0} {1} {2:X}”

  • String2 =“其他{0} {1} {2:X}”

  • String3 =“其他{0} {0} {2:X}”

  • String4 =“其他{0} {1} {2}”

  • String5 =“其他{0} {1}”

所以我需要检查的是:

  1. 所有字符串都包含相同数量的参数示例 缺少String5 {2:X}
  2. 该参数的错字也是正确的,例如String3 两次{0} {0}代替{0} {1}
  3. 格式也一样,例如String4最后一个参数不是 正确。

我不需要指定出什么问题,只需进行一般检查,例如如果相同则返回true或如果错误则返回false

我要做的是将字符串转换为CharaArray,然后遍历所有chara等。我认为这不是最佳解决方案

1 个答案:

答案 0 :(得分:0)

您可以使用正则表达式{(?<parameter>.+?)}提取所有参数。它将匹配开括号{,然后匹配任意数量的字符(尽可能小),然​​后再匹配闭括号}

此后,您可以将找到的所有参数分组,如果只有一组则意味着参数相同。要按字符串集合分组,您需要定义自定义相等比较器:

public class CustomEqualityComparer : IEqualityComparer<List<string>>
{
    public bool Equals(List<string> x, List<string> y)
    {
        if (x == null && y == null)
            return true;

        if (x == null || y == null)
            return false;

        return x.Count == y.Count && 
          x.Select((s, i) => (s: s, i: i)).All(t => t.s.Equals(y[t.i]));
    }

    public int GetHashCode(List<string> obj)
    {
        return obj.Aggregate(293, (c, n) => c ^ n.GetHashCode());
    }
}

用法:

var input = new[]
{
    "something {0} {1} {2:X}",
    "something else {0} {1} {2:X}",
    "something else {0} {0} {2:X}",
    "something else {0} {1} {2}",
    "something else {0} {1}",
};

var regex = new Regex("{(?<parameter>.+?)}");

var parameters = input
    .Select(i => 
        regex.Matches(i)
            .Cast<Match>()
            .Select(m => m.Groups["parameter"].Value)
            .ToList()
        )
    .GroupBy(x => x, new CustomEqualityComparer());

var areSame = parameters.Count() == 1;

如果您将输入定义为

var input = new[]
{
    "a {0} b {1} c",
    "{0} {1}",
};

areSame将为真


编辑

如果您的输入字符串取自string.FormatConsole.Write的第一个参数,则(如 canton7 在评论中所述),它们可以包含{{not a parametr}}之类的转义符。 。如果是这种情况,则需要将正则表达式修改为

(?<!{){(?!{)(?<parametr>.+?)}

说明:

(?<!{)          // check that there is no { char before
{               // match { literally 
(?!{)           // check that there is no { char after
  (             // start capturing group
    ?<parametr> // this capturing group name is "parametr"
    .+?         // match any char (except a new line) as few times as possible
  )             // end of capturing group
}               // match } literally 

Demo

请注意,此正则表达式可能与实际代码中将抛出FormatException的无效组(演示中的第4行)匹配。我希望这不是您的情况。

如果您的输入是由字符串插值构成的,例如

$"difficult { string.Concat(new[] { 's', 't', 'r', 'i', 'n', 'g' }) }"

我不知道实现所需目标的简单方法