Skip to main content
 首页 » 编程设计

c#之为什么这个正则表达式匹配额外的字段

2024年02月02日30findumars

第一次发布者,长期用户。我无法弄清楚为什么这个带有这个正则表达式的数据在它应该失败的时候却通过了。快速概述是我有一个文本文件,其中包含管道分隔的数据。我一次读取每一行,并与正则表达式进行比较以判断通过/失败。

这里是有问题的数据:

|A|00032004|00032004|25 S Kings Highway||Cape Giradeau|MO|63701|345800886888|0000254575|091091|RGT Foods, Inc.|1|345800886888|1|345800886888|1|601103061404806|1|003241699917|0|000000000000|0|000000000000|0|000000000000|0|000000000000| 
|A|00032005|00032005|1009 Kings Hwy||Rolla |MO|65401|345800885880|0000254564||RGT Foods, Inc.|1|345800885880|1|345800885880|1|601103061404798|1|003241699925|0|000000000000|0|000000000000|0|000000000000|0|000000000000| 

这是基本的分类: |D、U 或 A|ID#|ID#|St Add1|St Add2|城市|ST|Zip|#|#|Name|bool|#|bool|#|bool|#|bool|#|bool| #|bool|#|bool|#|bool|#|

这是我的正则表达式(警告:它有点长):

^[\|]{1}[DUA]{1}[\|]{1}[0-9,A-Z]{8}[\|]{1}[0-9,A-Z]{8}[\|]{1}.{0,25}[\|]{1}.{0,25}[\|]{1}.{0,25}[\|]{1}[A-Z,a-z]{2}[\|]{1}[0-9]{5}[\|]{1}[A-Z,a-z,0-9]{12}[\|]{1}[A-Z,a-z,0-9]{10}[\|]{1}.{0,25}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1}[0,1]{1}[\|]{1}[0-9]{15}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1}[0,1]{1}[\|]{1}[0-9]{12}[\|]{1} 

这是我的正则表达式函数:

//Compare the entire line at once 
public static bool MatchCCRegEx(string spLine) 
{ 
    try 
    { 
        Regex CCLineCheck = new Regex( 
                Properties.Settings.Default.CCRegExValidationString); 
        Match CCLineMatch = CCLineCheck.Match(spLine); 
 
        if (CCLineMatch.Success) 
            return true; 
        else 
            return false; 
    } 
    catch (Exception RegExCheckExc) 
    { 
        WELogger.LogEvent("3",  
            "Error running RegEx check on this line:\r\n"  
            + spLine + "\r\n" + RegExCheckExc.ToString()); 
 
        Environment.Exit(9); 
        return false; 
    } 
} 

我给出的示例数据应该会失败,因为在 # 和 Name 之间有一个值为 091091 的额外字段。第二行也应该因为额外字段而失败(但那一行是空的)。我盯着正则表达式看了好几个小时,因为在我看来,在“#|#|Name|bool”中,091091 会被放入名称和密码中,但是“RGT Foods, Inc.”。不应作为 0 或 1 传递...但两行都通过正则表达式,我做错了什么?

谢谢。

请您参考如下方法:

这是一个匹配项,因为 .{0,25} 不仅匹配 RGT Foods, Inc.,还匹配它之前的 091091| .

如果您知道您的“免费”字段不会包含任何管道,请将 .{0,25} 替换为 [^|]{0,25}。 (“0 到 25 个非管道字符”。)

另外,为了便于阅读,请注意

  • [\|]可以写成[|]或\|。
  • {1} 可以完全删除;默认是“匹配一次”。
  • [A-Z,a-z,0-9] 匹配 A-Z、a-z、0-9 和逗号。您的意思可能是 [A-Za-z0-9]。同样,[0,1] 应该是 [01] 而 [0-9,A-Z] 应该是 [0-9A- Z].

但老实说,如果您知道您的自由字段不能包含管道,我只是在管道上使用 String.Split 并分别验证每个字段。那个正则表达式是一场噩梦。