正则表达式从用户定义的id中提取序列号

时间:2016-01-21 18:14:43

标签: c# regex

我正在尝试从字符串ID中提取序列号,该ID可以设置为多种格式。该字符串由4个变量组成:

  • 公司代码/ char(3)
  • 国家/字符(2)
  • 年/ char(4)
  • 序列nr / char(5),左边用零填充

格式是可配置的,这意味着我们可以使用以下ID:

US-XXX-201600001

2016-XXX-00001-US

00001-XXX-US / 2016

...或任何其他定义的格式,但总是存在这4个变量。

问题是如何使用正则表达式(左边没有零)从我得到的任何格式获取序列号,但考虑到年份和序列nr可以像“201600001”一样。我只需要获得“1”

编辑:由于答案我想澄清那些只有一些可能的例子的格式。这完全可由用户定制。没有预定义的格式。这里唯一的常数是4个变量。 我知道用正则表达式来解决这个问题可能很复杂,而且我真的很喜欢你的所有答案。我会检查你提供的表达式,以检查哪一个更合适。

5 个答案:

答案 0 :(得分:1)

您需要在正则表达式中进行一些更改,以编程方式提取数字

US-XXX-(?:201[0-9])(\d{5})|(?:201[0-9])-XXX-(\d{5})-US|(\d{5})-XXX-US/(?:201[0-9])

这将与您的所有示例相符,请参阅a demo on regex101.com。但是,您需要对预期的输入格式更精确,然后您只需要遍历捕获的组。

答案 1 :(得分:1)

此正则表达式应捕获所有出现的内容。您需要在全局模式下运行它以获取所有组。即使在并非所有4个组都存在的情况下它也会匹配,但您可以稍后检查以确保它包含所有4个组。

它实际上并没有强制执行组排序的格式,只是每个组由-/分隔,除了年份和序列的情况,它允许不分开。

(?:(?<=^|-|\/)(?:(?P<cc>[A-Z]{2})|(?P<co>[A-Z]{3})|(?P<y>\d{4})|(?P<s>\d{5})|(?:(?P<y2>\d{4})(?P<cc2>\d{5})))(?=-|\/|$))+

https://regex101.com/r/uT2aU3/1

答案 2 :(得分:0)

对于每个变量,也许你必须使用多个正则表达式,如下所示:

Company code / char(3) = \b[A-Z]{3}\b
Country / char(2) = \b[A-Z]{2}\b
Year / char(4) = \b[0-9]{4}(?=[0-9]{5})|\b[0-9]{4}\b
Sequence nr / char(5), left padded with zeros = [0-9]{5}\b

答案 3 :(得分:0)

foo === bar.x

分成两个

当年份第一时,它与第一部分(第一组括号捕获数字)匹配:

/\b\d{4}0*(\d{1,5})(?<=\b\d{9})\b|\b0*(\d{1,5})(?<=\b\d{5})\b/

或没有年份(第二组括号捕获号码):

\b\d{4}0*(\d{1,5})(?<=\b\d{9})\b

细分:

  • \b0*(\d{1,5})(?<=\b\d{5})\b 是一个分词
  • \b是一个数字
  • \d是一个积极的背后照片&#39;:之前的匹配文字也与给定的正则表达式匹配(?<=X)
  • X表示正好四位数
  • \d{4}表示一到五位数字

https://regex101.com/r/rP2wZ4/1

答案 4 :(得分:0)

不将知道插入模式中是愚蠢的......那么为什么要阻碍这个过程呢?

这些都是在第一个模式运行之前已知的所有国家。 21世纪的一年怎么样?

此模式将知识列为每行的单独模式匹配,然后将每行的各个匹配加载到实体中,以便通过命名捕获轻松提取。

var datas = new List<string>()
{
"US-XXX-201600001",
"2016-YYY-86753-FR",
"09012-ZZZ-GB/2016"
};

var pattern = @"
(?<Country>US|FR|GB)  -- All Countries or'ed together.
          | 
(?<Year>20\d\d)       -- Only in the 21st century.
          |
(?<Company>XXX|YYY|ZZZ) -- All Company names are known and or'ed.
          |
(?<FullId>0{0,4}(?<Id>\d{1,5})) -- IDs have to have a number greater than 1.";


datas.Select(str =>  Regex.Matches(str, 
                                   pattern, 
                                  RegexOptions.ExplicitCapture | 
                                  RegexOptions.IgnorePatternWhitespace)
                          .OfType<Match>())
     .Select(mtchs => new Credentials(mtchs) );

<强>结果

enter image description here

专业实体类

这个类完成了一些提取数据并将其加载到目标属性中的脚部工作。

public class Credentials
{
    public string Id { get; set; }
    public string FullId { get; set; }
    public string Year { get; set; }
    public string Country { get; set; }
    public string Company { get; set; }

    public Credentials(IEnumerable<Match> matches)
    {
        var properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();

        matches.ToList()
               .ForEach(mt => properties.ForEach(prp => AssignValid(prp, mt, prp.Name)));
    }

    public void AssignValid(PropertyInfo prop, Match mt, string name)
    {
        if (mt.Groups[name]?.Success ?? false)
            prop.SetValue(this, (mt.Groups[name].Value));
    }
}