正则表达式可从一长串没有分区的代码中拆分出不同的代码

时间:2019-06-28 15:38:57

标签: c# regex

(基本上)我有一个大约600,000个代码的文件。

它们看起来像这样:

HJ43EKU2

存储/加载它们时,它们看起来像这样:

BJX4700QHJ43EKU2KU89EJKM

每个代码正好是8位数字。

它们是字母数字(a-Z,0-9),没有重音符号。

所以这可行(用于拆分代码块):

[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]

但是存在一个问题,因为某些格式的代码不是像这样的有效代码:

MF93276H

第7位数字不能为数字。

这不会太糟,除了代码的第二位是否为N(或字母的第二位)之外,这将使代码再次有效。

我该如何对REGEX实现一些逻辑,以便它考虑到重新验证代码的规则的“例外”?

3 个答案:

答案 0 :(得分:3)

在C#中,您可以使用捕获组并随后对其进行评估的已知技术:

var rx = "[a-zA-Z0-9]N[a-zA-Z0-9]{4}[0-9][a-zA-Z0-9]|([a-zA-Z0-9]{6}[0-9][a-zA-Z0-9])|[a-zA-Z0-9]{6}[a-zA-Z][a-zA-Z0-9]";
var results = Regex.Matches("BJX4700QHJ43EKU2KU89EJKM", rx)
            .Cast<Match>()
            .Where(m => !m.Groups[1].Success)
            .Select(z => z.Value);
foreach (var s in results)
    Console.WriteLine(s);

请参见C# demo

正则表达式详细信息

  • [a-zA-Z0-9]N[a-zA-Z0-9]{4}[0-9][a-zA-Z0-9]-有效的代码模式,第二个字符等于N
  • |-或
  • ([a-zA-Z0-9]{6}[0-9][a-zA-Z0-9])-第1组(如果匹配,则将其丢弃):无效的代码模式
  • |-或
  • [a-zA-Z0-9]{6}[a-zA-Z][a-zA-Z0-9]-有效的代码模式。

注意:如果 N(或字母的后面)表示如果第二个字符为O,则P .. {{ 1}},则需要将第一个替代方案中的Z替换为N

代码详细信息

  • [N-Z]-如果第1组不匹配,则该匹配为有效代码,因此仅获取那些
  • .Where(m => !m.Groups[1].Success)-仅将整个匹配对象值文本保留在结果中。

答案 1 :(得分:1)

我不能强烈建议 ,但是.NET实际上支持条件组,因此您可以做到:

var pattern = "[a-zA-Z0-9](?:(?<n>N)|[a-zA-Z0-9-[nN]])[a-zA-Z0-9]{4}(?(n)[a-zA-Z0-9]|[a-zA-Z])[a-zA-Z0-9]";
Regex.IsMatch("MF93276H") // false
Regex.IsMatch("MN93276H") // true

答案 2 :(得分:1)

我会使用其他结构:

var x = @"HJ43EKU2";
var match =
    Regex.Match(x, @"(?i)[a-z0-9](?([n-z])[a-z0-9]{7}|[a-z0-9]{5}[a-z][a-z0-9])");
var code = match.Value;

(?i)使搜索不区分大小写

(?(n-z))零宽度断言,用于检查第二个字符是N还是“更多”

[a-z0-9]{7}如果第二个字符 N,则允许第7个字符为数字

[a-z0-9]{5}[a-z][a-z0-9]如果第二个字符不是 N或更高,请不允许将第七个字符设为数字