匹配正则表达式中的模式

时间:2013-06-18 14:51:38

标签: c# regex regex-group

我正在开发一个通用应用程序,我需要匹配一个我无法解决的模式。

输入字符串可以是:

12_B 99-23_9_23

正如您在示例中所看到的,我的问题是当我想匹配此模式“B 99-23”时。 分隔符可以是任何东西,不仅仅是下划线(例如12 | B 99-23 | 9 | 23)

现在这就是我的......

Regex r = new Regex("^(?< pol>\\w+)_(?< fac>\\w+)_(?< end>\\w+)_(?< op>\\w+)");

我必须更改此部分: (?< fac>\\w+) 该模式必须采取一切直到下一个分隔符('_'),包括空格,数字,字符。 然后我会得到这个结果:

pol = 12
fac = B 99-23
end = 9
op = 23

2 个答案:

答案 0 :(得分:2)

尝试使用此模式:

^(?< pol>\w+)_(?< fac>[^_]+)_(?< end>\w+)_(?< op>\w+)

[^_]character class表示'匹配除下划线以外的任何内容'。如果分隔符为|,则必须在模式中使用\|,因为|在正则表达式中具有特殊含义(尽管您不需要在字符内转义它类)。像这样:

^(?< pol>\w+)\|(?< fac>[^|]+)\|(?< end>\w+)\|(?< op>\w+)

在旁注中,我发现在指定正则表达式模式时使用逐字符串更容易,因为您不必键入如此多的转义序列:

new Regex(@"^(?< pol>\w+)\|(?< fac>[^|]+)\|(?< end>\w+)\|(?< op>\w+)");

但是,在这种情况下,您最好只使用Split

var result = input.Split(new char[] { '_' }, 4);
// result[0] = 12
// result[1] = B 99-23
// result[2] = 9
// result[3] = 23

答案 1 :(得分:0)

描述

部分问题是\w还包括所有字母a-z,全部为0-9,以及下划线_。因此,如果您的输入文本可以使用_分隔符,那么匹配\w+的表达式将会混淆

因为您需要允许使用下划线作为分隔符,我建议您不要使用简写\w,而是为所需的文本和分隔符定义您想要的字符类。

  • [0-9a-zA-Z]+将按任意顺序匹配一个或多个alphebetical或数字
  • [^a-zA-Z0-9]这是一个否定的字符类,会匹配任何非字母或数字的字符

此正则表达式将匹配所有值,并允许多种分隔符。

^(?<pol>[0-9a-zA-Z]+)[^a-zA-Z0-9](?<fac>[0-9a-zA-Z]+\s[0-9a-zA-Z]+-[0-9a-zA-Z]+)[^a-zA-Z0-9](?<end>[0-9a-zA-Z]+)[^a-zA-Z0-9](?<op>[0-9a-zA-Z]+)

enter image description here

为了匹配fac组,我假设该字段的格式为:Letter Space Numbers连字符数字。

  • 组0将获得整个匹配的字符串
  • 将创建命名组,但在图像中1 = pol,2 = fac,3 = end,4 = op。很抱歉绘图软件无法处理命名捕获组。

C#代码示例:

输入文字

12_B 99-23_9_23
11_a 11-11_1_11
22|b 22-22|2|22
33-c 33-33-3-33
44,d 44-44,4,44

代码

using System;
using System.Text.RegularExpressions;
namespace myapp
{
  class Class1
    {
      static void Main(string[] args)
        {
          String sourcestring = "source string to match with pattern";
          Regex re = new Regex(@"^(?<pol>[0-9a-zA-Z]+)[^a-zA-Z0-9](?<fac>[0-9a-zA-Z]+\s[0-9a-zA-Z]+-[0-9a-zA-Z]+)[^a-zA-Z0-9](?<end>[0-9a-zA-Z]+)[^a-zA-Z0-9](?<op>[0-9a-zA-Z]+)",RegexOptions.IgnoreCase | RegexOptions.Multiline);
          MatchCollection mc = re.Matches(sourcestring);
          int mIdx=0;
          foreach (Match m in mc)
           {
            for (int gIdx = 0; gIdx < m.Groups.Count; gIdx++)
              {
                Console.WriteLine("[{0}][{1}] = {2}", mIdx, re.GetGroupNames()[gIdx], m.Groups[gIdx].Value);
              }
            mIdx++;
          }
        }
    }
}

匹配

$matches Array:
(
    [0] => Array
        (
            [0] => 12_B 99-23_9_23
            [1] => 11_a 11-11_1_11
            [2] => 22|b 22-22|2|22
            [3] => 33-c 33-33-3-33
            [4] => 44,d 44-44,4,44
        )

    [pol] => Array
        (
            [0] => 12
            [1] => 11
            [2] => 22
            [3] => 33
            [4] => 44
        )


    [fac] => Array
        (
            [0] => B 99-23
            [1] => a 11-11
            [2] => b 22-22
            [3] => c 33-33
            [4] => d 44-44
        )


    [end] => Array
        (
            [0] => 9
            [1] => 1
            [2] => 2
            [3] => 3
            [4] => 4
        )


    [op] => Array
        (
            [0] => 23
            [1] => 11
            [2] => 22
            [3] => 33
            [4] => 44
        )


)