2011-06-23 145 views
8

我不寫很多正則表達式,所以我需要一些幫助。正則表達式的幫助 - 逗號分隔的字符串

我需要一個正則表達式,可以驗證字符串是一個字母數字逗號分隔的字符串。

例子:

  • 123, 4A67, GGG, 767將是有效的。
  • 12333, 78787&*, GH778將是無效的
  • fghkjhfdg8797<將是無效的

這是我到目前爲止,但並不完全正確:^(?=.*[a-zA-Z0-9][,]).*$

有什麼建議?

+0

你的正則表達式的意思是「比賽如果下位匹配,但不消耗,任何一個字符,然後包括AZ,az之一,或0-9,然後是一個逗號,然後在字符串結尾之前消耗任何一個字符。「這是不可能匹配任何東西的,因爲不消費部分必須匹配三個字符,包括尾部逗號,在消費部分到來之前,並且只能匹配一件事情。 – markets

+0

@markets:OP沒有使用代碼格式,所以兩個'*'量詞不可見。正則表達式仍然是錯誤的,但它現在更有意義了。 ;)@JohnH:如果你使用SO的格式化工具,你會得到更好的結果;他們非常好。 –

回答

15

聽起來像是你需要這樣的表達式:

[0-9a-zA-Z]+(,[0-9a-zA-Z]+)* 

的Posix允許更多的自我描述的版本:

[[:alnum:]]+(,[[:alnum:]]+)* 
[[:alnum:]]+([[:space:]]*,[[:space:]]*[[:alnum:]]+)* // allow whitespace 

如果你願意承認下劃線,也在尋找整個字(\w+):

\w+(,\w+)* 
\w+(\s*,\s*\w+)* // allow whitespaces around the comma 

( !感謝阿蘭指出我的幾個失誤的)

+2

這個答案有幾個問題:(1)POSIX「字符類」不能直接使用;它必須被包圍在另一組方括號中,例如, '[[:alnum:]] +'。但是這是理論上的,因爲.NET不支持它們(甚至不是以不同的形式,比如Java的'\ p {Alnum}')。 (2)'\ w'與所有字符類的簡寫('\ s','\ d'等)一樣,只匹配一個字母,所以你應該使用'\ w +'。 (3)你不允許在令牌之間留下空白。 –

+0

@Alan:謝謝,修正!順便說一下,Emacs中的「空白」是什麼? '\ s'似乎不起作用... –

+1

我不使用Emacs,但根據[this](http://www.emacswiki.org/emacs/RegularExpression),它是'\ s-'。 \ s'本身不匹配任何東西;它只是將以下字符標記爲特殊。 –

1

嘗試這種模式:^([a-zA-Z0-9]+,?\s*)+$

我與你的情況下進行了測試,以及只是一個單一的數字「123」。我不知道你是否總是有逗號。

[a-zA-Z0-9]+意味着匹配1個或多個這些符號的 的,?意味着匹配0或1逗號(基本上,逗號是可選的) 的\s*處理1個或多個空格逗號之後 最後是外+說匹配1個或更多的模式。

這也將匹配 123 123 abc(沒有逗號),這可能是一個問題 這也將匹配123,(用逗號結尾),這可能是一個問題。

0

你似乎缺乏重複。如何:

^(?:[a-zA-Z0-9 ]+,)*[a-zA-Z0-9 ]+$ 

我不知道你會如何表達,在VB.Net,但在Python:

>>> import re 
>>> x [ "123, $a67, GGG, 767", "12333, 78787&*, GH778" ] 
>>> r = '^(?:[a-zA-Z0-9 ]+,)*[a-zA-Z0-9 ]+$' 
>>> for s in x: 
... print re.match(r, s) 
... 
<_sre.SRE_Match object at 0xb75c8218> 
None 
>>>> 

您可以使用,而不是列出的[a-zA-Z0-9 ]部分快捷鍵,但是這可能更容易理解。

判斷亮點:

  • [a-zA-Z0-9 ]+:捕獲列出的範圍中的一個或多個(但不是零),和空間。
  • (?:[...]+,)*:在非捕獲括號中,匹配一個或多個字符,並在末尾加上逗號。匹配這樣的序列零次或多次。捕獲零次不允許使用逗號。
  • [...]+:捕獲其中至少一個。這不包括逗號。這是爲了確保它不接受尾隨逗號。如果後面的逗號是可以接受的,則表達式是比較容易:^[a-zA-Z0-9 ,]+
+0

這允許任何地方的空間,所以它也會匹配''abc 123,fo o bar''。也許這對於OP來說是可以接受的,但是我會從字符類中拉出空格。 –

+0

@Alan好點。 OP沒有解決空間問題,只是在例子中允許它們。正則表達式可以刪除現有空格,並在逗號前後添加可選空格(空格 - 星號)。 – markets

1

是的,當你想趕上逗號分隔東西的地方在最後一個逗號是法律,以及東西匹配$LONGSTUFF,你不得不重複$LONGSTUFF

$LONGSTUFF(,$LONGSTUFF)* 

如果$LONGSTUFF是很長的,包含逗號重複項目本身等,這可能是一個好主意,建立用手正則表達式,而是依靠在計算機上做這件事爲喲ü,即使它只是通過字符串連接。例如,我只是想構建一個正則表達式來驗證['1:a=b,c=d','2:e=f,g=h']類型的XEN configuration file的CPUID參數。我......相信這主要是符合該法案:(!儘管有空格)

xend_fudge_item_re = r""" 
    e[a-d]x=   #register of the call return value to fudge 
    (
    0x[0-9A-F]+ | #either hardcode the reply 
    [10xks]{32}  #or edit the bitfield directly 
) 
""" 
xend_string_item_re = r""" 
    (0x)?[0-9A-F]+: #leafnum (the contents of EAX before the call) 
    %s    #one fudge 
    (,%s)*   #repeated multiple times 
""" % (xend_fudge_item_re, xend_fudge_item_re) 
xend_syntax = re.compile(r""" 
    \[    #a list of 
    '%s'    #string elements 
    (,'%s')*   #repeated multiple times 
    \] 
    $     #and nothing else 
""" % (xend_string_item_re, xend_string_item_re), re.VERBOSE | re.MULTILINE) 
+0

請注意,上述RE有幾個問題,包括但不限於缺乏空白支持和區分大小寫,這使得它不值得生產。固定版本比較長,然後你會開始錯過答案的要點。這只是一個如何處理更復雜的案例的例子。 – badp

+0

我沒有結束使用該正則表達式 - 因此[這是完整的shebang](https://gist.github.com/badp/6353579) – badp

相關問題