[英]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.