【问题标题】:C# Regular Expression Capturing Empty String [duplicate]C#正则表达式捕获空字符串[重复]
【发布时间】:2017-09-22 20:37:47
【问题描述】:

我正在尝试在 C# 中创建一个简单的正则表达式来将字符串拆分为标记。我遇到的问题是我使用的模式捕获了一个空字符串,这会抛出我的预期结果。我可以做些什么来更改我的正则表达式,使其不捕获空字符串?

var input = "ID=123&User=JohnDoe";
var pattern = "(?:id=)|(?:&user=)";
var tokens = Regex.Split(input, pattern, RegexOptions.IgnoreCase);

// Expected Results
// tokens[0] == "123"
// tokens[1] == "JohnDoe"

// Actual Results
// tokens[0] == ""
// tokens[1] == "123"
// tokens[2] == "JohnDoe"

【问题讨论】:

  • 链接不回答 OP - 它依赖于 .NET 核心中不存在的 System.Net.Http 静态方法
  • @WiktorStribiżew 绝对指出了一种更好的方法。您的查询字符串在语义相同的输入 "User=JohnDoe&ID=123" 上会失败,因为您在正则表达式中检查了 &。最好不要在这个上重新发明轮子。
  • 有几种方法可以解决这个问题。 1)Remove empty items,2)使用(?i)(?<=id=)[^&]+获取id,(?i)(?<=user=)[^&]+获取用户名,3)等等

标签: c# regex


【解决方案1】:

虽然关于使用不同方法的 OP 的 cmets 可能有优点,但它们并没有解决您关于 RegEx 行为的具体问题。

我认为尽管您获得正则表达式行为的原因与隐式捕获组有关(编辑:或者它可能只是限制第一组的捕获行为就足够了),但我还没有它是对 RegEx 层次结构的顶层理解。

编辑:

给定测试用例的工作正则表达式:

(?>id=)|(?:&user=)

如果这些都不符合你的喜好,你总是可以在标记列表中添加一个谓词:

tokens.Where(x => !string.IsNullOrWhiteSpace(x))

【讨论】:

    【解决方案2】:

    老实说,我不认为你可以用Regex.Split 解决这个问题。执行此操作的一种蛮力方法是删除每个 "":

    var input = "ID=123&User=JohnDoe";
    var pattern = "(?:id=)|(?:&user=)";
    var tokens = Regex.Split(input, pattern, RegexOptions.IgnoreCase).Where(x => x != "");
    

    我认为您应该使用真正按组捕获标记的正则表达式。

    var input = "ID=123&User=JohnDoe";
    var pattern = "id=(.+)&user=(.+)";
    var match = Regex.Match(input, pattern, RegexOptions
        .IgnoreCase);
    match.Groups[1] // 123
    

    【讨论】:

      猜你喜欢
      • 2012-08-20
      • 2018-03-22
      • 2019-09-02
      • 2020-10-26
      • 2020-07-12
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      相关资源
      最近更新 更多