第一次海报,长时间用户。我无法弄清楚为什么这个正则表达式的数据在失败时会传递。快速概述我有一个文本文件,其中包含管道分隔数据。我一次只读一行,并与正则表达式进行通过/失败比较。
以下是有问题的数据:
|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 | City | ST | Zip |#|#| Name | 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 :(得分:4)
这是匹配,因为.{0,25}
不仅与RGT Foods, Inc.
匹配,还与之前的091091|
匹配。
如果您知道“免费”字段不包含任何管道,请将.{0,25}
替换为[^|]{0,25}
。 (“零至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
并分别验证每个字段。那个正则表达式是一场噩梦。
答案 1 :(得分:1)
问题在于,您允许|
作为分隔符之间匹配的一部分。你可能不想这样做。此外,您可以减少大量的多余括号,因为{1}
是不必要的。您可能不想允许使用逗号:
^\|[DUA]\|[0-9A-Z]{8}\|[0-9A-Z]{8}\|[^|]{0,25}\|[^|]{0,25}\|[^|]{0,25}\|[A-Za-z]{2}\|[0-9]{5}\|[A-Za-z0-9]{12}\|[A-Za-z0-9]{10}\|[^|]{0,25}\|[01]\|[0-9]{12}\|[01]\|[0-9]{12}\|[01]\|[0-9]{15}\|[01]\|[0-9]{12}\|[01]\|[0-9]{12}\|[01]\|[0-9]{12}\|[01]\|[0-9]{12}\|[01]\|[0-9]{12}\|
答案 2 :(得分:0)
.{0,25}
匹配任何内容(长度为0-25),包括 |
。尝试[^\|]{0,25}
排除|
s。
答案 3 :(得分:0)
我建议使用为此任务构建的库,而不是使用正则表达式来解析分隔文件。
一个受欢迎的选项是FileHelpers,Microsoft.VisualBasic.FileIO
具有为此制作的TextFieldParser类。