【问题标题】:C# Regex syntax for pattern模式的 C# 正则表达式语法
【发布时间】:2017-08-10 16:32:44
【问题描述】:

在继续之前,我需要使用 C# 中的正则表达式确保字段具有正确的语法。这是我的代码:

Description = 'AB1234567,AB3456789;AB2345678';

Regex reg = new Regex("(AB.{7},?)*;?(AB.{7},?)*");
Match match = reg.Match(Description);
if (!match.Success)
{
    //code to raise error
}

所以,一些语法规则:

  • 该字段包含 2 个字母(在本例中为 AB)后跟 7 个字符的元素。
  • 这些元素以逗号分隔,位于“;”的左侧或右侧。它们在哪一边表示它们的属性,但任何一边都可以是空的。
  • 如果右侧不为空,则“;”为必填项,如果为空则为可选项。
  • 每边的最后一个元素不能以“,”结尾。

正确示例:

 - AB1234567,AB3456789;AB2345678
 - AB1234567,AB3456789;
 - AB1234567
 - ;AB2345678,AB34567890

错误示例:

 - AB1234567,;AB2345678
 - AB3456789;AB2345678,

我的正则表达式不完整,但我想不出如何考虑所有情况。这个问题的正确正则表达式是什么?

【问题讨论】:

  • 最终目标是什么?你需要提取列表中的AB***吗?
  • 是的,分成两个列表。
  • 好的,这里的正则表达式应该可以工作 (?AB\d{7}[,;]) 您将收到匹配作为命名组。 goto: regex101.com 输入你的正则表达式和测试数据..你会做的很好..
  • 好的,你自己去投票吧。

标签: c# regex


【解决方案1】:

直截了当的答案和更简化的版本,应该适用于所有选项。

    bool  IsValid(string line)
    {
        if (string.IsNullOrEmpty(line)) return true;
        return !line.Trim().EndsWith(",");
    }

    IEnumerable<string> GetTokens(string line)
    {
        var pattern = @"(AB\d{7}([,;]|[^0-9a-zA-Z]|$))";
        var matches = Regex.Matches(line, pattern, RegexOptions.Singleline);

        foreach (Match match in matches)
        {
            yield return match.Value;
        }
    }

    string inputLine = ";AB2345678,AB34567890";

    string[] leftRight = inputLine.Split(new[] { ';' });
    string left =string.Empty, right = string.Empty;

    if (leftRight.Length > 0) left = leftRight[0];
    if (leftRight.Length > 1) right = leftRight[1];

    bool isLeftValid = IsValid(left);
    bool isRightValid = IsValid(right);

    IEnumerable<string> leftTokens = null, rightTokens = null;

    if (isLeftValid) leftTokens = GetTokens(left);
    if (isRightValid) rightTokens = GetTokens(right);

【讨论】:

    【解决方案2】:

    我认为您的表达几乎是正确的,您只需要确保逗号后跟另一个AB 组。您可以使用positive lookahead 来做到这一点,如下所示:

    ^(AB.{7}(,(?=AB))?)*;?(AB.{7}(,(?=AB))?)*$
    

    您还需要输入开始和结束标记,否则您将获得多个子匹配。

    此表达式将不匹配 ;AB2345678,AB34567890 样本,因为它在最后一组中有 8 位而不是 7 位

    编辑:如果您希望 AB 组在一个不错的集合中,请尝试

    ^((?<left>AB.{7})(,(?=AB))?)*;?((?<right>AB.{7})(,(?=AB))?)*$
    

    然后match.Groups["left"]?.Capturesmatch.Groups["right"]?.Captures 将为您提供各自匹配的字符串(或空)。这称为命名捕获。

    【讨论】:

    • 反对者愿意解释吗?给定的表达式适用于所有样本(除了我提到的不符合描述的那个)。你可以在这里查看:regexstorm.net/tester
    猜你喜欢
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多