【问题标题】:How to match "Parameter Name: Value" in C# Regex?如何在 C# Regex 中匹配“参数名称:值”?
【发布时间】:2009-04-03 13:34:55
【问题描述】:

我想匹配这些行:

ParameterINeed: 758
ParameterCount: 8695
ParameterText: 56

我会收到一个参数名称和参数值。你能告诉我如何为此编写 Regex.Matches 模式以及如何将这些数据处理到字典中吗?

我使用这个代码:

string Text = "ParameterINeed: 758\r\nParameterCount: 8695\r\nParameterText: 56";
string Pattern = "^(\\w+):\\s+(\\d+)$";
MatchCollection ma = Regex.Matches(Text, Pattern, RegexOptions.Singleline);

得到 ma.Count = 0

【问题讨论】:

  • 代码无法编译。 (“\w”不是有效的转义序列。)粘贴您实际使用的代码...
  • 刚刚修好了。在 \w 中的 \ 之前放置一个 \,它将编译。
  • 是的,我已经自己“修复”了它,但为什么不粘贴您正在使用的实际代码呢?
  • @Guffa - 这是我正在使用的实际代码。你还需要什么?

标签: c# regex


【解决方案1】:

试试这个正则表达式

"^Parameter(\w+):\s+(\d+)$"

然后您可以通过 Matches[1] 访问名称并将值作为 Matches[2]。我的回答是基于字符串 ParameterINeed: 42 you want

  • 姓名:需要
  • 值:42

如果您想要 ParameterINeed 作为值,您可以从正则表达式中删除 Parameter 字。

"^(\w+):\s+(\d+)$"

编辑响应添加的代码示例

请尝试以下示例

string Text = "ParameterINeed: 758\r\nParameterCount: 8695\r\nParameterText: 56";
string[] lines = Text.Split("\n");
string Pattern = @"^(\w+):\s+(\\d+)$";
foreach ( string line in lines ) {
  MatchCollection ma = Regex.Matches(line, Pattern, RegexOptions.Singleline);
}

【讨论】:

  • 当我这样做时,它只匹配文本中的最后一个参数。
  • 哦,有没有办法在没有 foreach 循环的情况下做到这一点?
  • @tomaszs,一般来说,使用正则表达式来处理新行更难。您可以使用其中之一,但它使推理匹配集合中的值变得更加困难。您是否有不想循环处理它的原因?
  • @JaredPar - 我想摆脱任何类型的拆分和循环,以便它成为纯粹的、独立的正则表达式。有了这种分裂,就好像建造了一座金属桥,其中一部分是用绳子制成的。
  • 仅当正则表达式是绳子时。
【解决方案2】:

RegexOptions.SingleLine 仅影响句点标记的工作方式,而不影响 ^ 和 $ 标记的工作方式。为此,您需要使用RegexOptions.MultiLine

多行模式不理解 \r\n 换行符,它只将 \n 字符视为换行符。您必须使用 \r 字符才能到达换行符。

string text = "ParameterINeed: 758\r\nParameterCount: 8695\r\nParameterText: 56";
string pattern = @"^(\w+):\s+(\d+)\r?$";
MatchCollection ma = Regex.Matches(text, pattern, RegexOptions.Multiline);

现在ma.Count 是 3。

这就是您将匹配项放入字典中的方式:

Dictionary<string, int> values = new Dictionary<string, int>();
foreach (Match match in ma) {
    values.Add(match.Groups[1].Value, int.Parse(match.Groups[2].Value));
}

【讨论】:

  • SingleLine 导致 $ 匹配字符串的结尾。其中 as Multiline 导致 $ 匹配第一个新行。
  • @AnthonyWJones:不,SingleLine 根本不会改变 $ 的工作方式,它只会改变期间的工作方式。多行导致 $ 匹配每行的结尾,而不是换行符。
【解决方案3】:

这是一个经过测试的解决方案。 ;)

static void Main(string[] args)
{
    try
    {

        string sInput;

        // The string to search.
        sInput = "ParameterINeed: 758\r\nParameterCount: 8695\r\nParameterText: 56";


        var regex = new Regex(@"(?<parameter>\w+):\s+(?<value>\d+)");
        var dictionary = new Dictionary<string, string>();

        foreach (Match match in regex.Matches(sInput))
        {
            dictionary.Add(
            match.Groups["parameter"].Value, 
            match.Groups["value"].Value); 
        }

        foreach (KeyValuePair<string, string> item in dictionary)
            Console.WriteLine("key: {0}; value:{1}", item.Key, item.Value);

    }
    finally
    {
        Console.ReadKey();
    }

}

【讨论】:

    【解决方案4】:

    你为什么不简单地按行分割,然后用 ':' 分割文本并修剪结果? 还是更复杂的问题?

    【讨论】:

    • 我想用正则表达式来做这个以备将来更改
    • 我明白了。那么它必须是正则表达式。
    【解决方案5】:

    没有使用过 C#,我无法给出直接的代码示例。

    如果它遵循正常的正则表达式模式,问题可能是 ^/$.. 通常匹配字符串开头 (^) 和字符串结尾 ($) 不一定是“行尾”。

    如果你尝试类似的东西(用 perl 测试):

    /(\w+):\s(\w+)(?:\r\n)?/g

    【讨论】:

      【解决方案6】:

      取决于其他一些约束,但你可以使用它。

      var regex = new Regex(@"^($<parameter>\w+):\s($<value>\d+)$");
      var dictionary = new Dictionary<string, string>();
      
      foreach(var match in regex.Matches(inputData, RegexOptions.Multiline))
      {
        dictionary.Add(
          match.Groups["parameter"].Value, 
          match.Groups["value"].Value);
      }
      

      【讨论】:

      • 目前无法测试,请尝试使用 RegexOptions
      • 请在投反对票时发表评论。
      猜你喜欢
      • 2018-06-15
      • 1970-01-01
      • 2018-10-15
      • 2021-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多