[英]Regex doesn't give me expected result
好的,我放弃了-是时候请正则表达式专家寻求帮助了。
我正在尝试验证CSV文件的内容,只是看它是否看起来像预期的有效CSV数据。 我并不是要验证所有可能的CSV表单,只是要使它“看起来像” CSV数据,而不是二进制数据,代码文件或其他内容。
每行数据包含逗号分隔的单词,每个单词包含az
, 0-9
和少量标点符号,即-
和_
。 文件中可能有几行。 而已。
这是我的简单代码:
const string dataWord = @"[a-z0-9_\-]+";
const string dataLine = "("+dataWord+@"\s*,\s*)*"+dataWord;
const string csvDataFormat = "("+dataLine+") | (("+dataLine+@"\r\n)*"+dataLine +")";
Regex validCSVDataPattern = new Regex(csvDataFormat, RegexOptions.IgnoreCase);
protected override bool IsCorrectDataFormat(string fileContents)
{
return validCSVDataPattern.IsMatch(fileContents);
}
这给了我一个正则表达式模式
(([a-z0-9_\-]+\s*,\s*)*[a-z0-9_\-]+) | ((([a-z0-9_\-]+\s*,\s*)*[a-z0-9_\-]+\r\n)*([a-z0-9_\-]+\s*,\s*)*[a-z0-9_\-]+)
但是,如果我用一段C#代码来呈现它,则正则表达式解析器会说这是匹配项。 那个怎么样? C#代码看起来不像我的CSV模式(开始时,除了_
和-
以外,还有标点符号)。
谁能指出我明显的错误? 让我重复一遍-我并不是要验证所有可能的CSV表单,而只是验证我的简单子集。
您的正则表达式缺少^
(行的开头)和$
(行的结尾)锚。 这意味着它将与包含该表达式描述的内容的任何文本匹配,即使该文本包含其他完全不相关的部分。
例如,此文本与表达式匹配:
foo, bar
因此,此文本还与以下内容匹配:
var result = calculate(foo, bar);
您可以看到前进的方向。
在csvDataFormat
的开头添加^
,在结尾添加$
,以获取所需的行为。
这是一种更好的模式,用于在每行中一对多查找CSV组(例如XXX,
或yyy
:
^([\w\s_\-]*,?)+$
^
-每行的开头
(
-CSV匹配组开始
[\\w\\s_\\-]*
-每个CSV中的有效字符\\w (a-zA-Z0-9)
以及_
和-
,?
-可能是逗号
)+
-csv匹配组的末尾,其中有1个是预期的。
这将验证整个文件,一行行的基本CSV结构,并允许空,,
情况。
我想出了这个正则表达式:
^([a-z0-9_\-]+)(\s*)(,\s*[a-z0-9_\-]+)*$
测试
asbc_- , khkhkjh, lkjlkjlkj_-, j : PASS
asbc, : FAIL
asbc_-,khkhkjh,lkjlkjlk909j_-,j : PASS
如果你想匹配空行一样,,,
或者当某些值是空白样,abcd,,
使用
^([a-z0-9_\-]*)(\s*)(,\s*[a-z0-9_\-]*)*$
循环浏览所有行以查看文件是否正常:
const string dataLine = "^([a-z0-9_\-]+)(\s*)(,\s*[a-z0-9_\-]+)*$";
Regex validCSVDataPattern = new Regex(csvDataFormat, RegexOptions.IgnoreCase);
protected override bool IsCorrectDataFormat(string fileContents)
{
string[] lines = fileContents.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
foreach (var line in lines)
{
if (!validCSVDataPattern.IsMatch(line))
return false;
}
return true;
}
我认为这是您要寻找的:
@"(?in)^[a-z0-9_-]+( *, *[a-z0-9_-]+)*([\r\n]+[a-z0-9_-]+( *, *[a-z0-9_-]+)*)*$"
值得注意的变化是:
^
和$
,因为没有它们的正则表达式是毫无意义的 \\s
在每次出现\\s*
与文字空间(因为\\s
可以匹配任何空白字符,而您只希望匹配这些点实际的空间) 在此之前,您的正则表达式的基本结构看起来还不错|
来了,把事情搞砸了。 ;)
ps,以防万一, (?in)
是一个内联修饰符,用于设置IgnoreCase
和ExplicitCapture
模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.