2011-06-23 35 views
8

Tôi không viết nhiều cụm từ thông dụng vì vậy tôi cần một số trợ giúp trên biểu thức.Trợ giúp biểu thức chính quy - chuỗi phân cách bằng dấu phẩy

Tôi cần cụm từ thông dụng có thể xác thực rằng chuỗi là chuỗi phân tách bằng dấu phẩy và chữ số.

Ví dụ:

  • 123, 4A67, GGG, 767 sẽ là hợp lệ.
  • 12333, 78787&*, GH778 sẽ là không hợp lệ
  • fghkjhfdg8797< sẽ là không hợp lệ

Đây là những gì tôi có cho đến nay, nhưng không phải là hoàn toàn đúng: ^(?=.*[a-zA-Z0-9][,]).*$

Bất kỳ lời đề nghị?

+0

Cụm từ thông dụng của bạn có nghĩa là "khớp với bit tiếp theo, nhưng không tiêu thụ, bất kỳ char nào, sau đó là az, AZ hoặc 0-9, theo sau là một trong số: dấu phẩy. Sau đó, sử dụng bất kỳ ký tự nào trước khi kết thúc chuỗi. " Nó không thể cho điều này để phù hợp với bất cứ điều gì, vì phần không tiêu thụ phải phù hợp với ba ký tự, bao gồm một dấu phẩy, trước khi phần tiêu thụ đến và chỉ có thể phù hợp với một điều. – markets

+0

@markets: OP không sử dụng định dạng mã, do đó, hai bộ định lượng '*' không hiển thị. Regex vẫn còn sai, nhưng bây giờ nó có ý nghĩa hơn một chút. ;) @JohnH: Bạn sẽ nhận được kết quả tốt hơn nếu bạn sử dụng các công cụ định dạng của SO; Họ rất tốt. –

Trả lời

15

Âm thanh như bạn cần một biểu hiện như thế này:

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

Posix cho phép tự mô tả phiên bản hơn:

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

Nếu bạn sẵn sàng thừa nhận dấu gạch dưới, quá, tìm kiếm toàn bộ các từ (\w+):

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

(! Nhờ Alan đã chỉ ra một số khuyết điểm của tôi)

+2

Một vài vấn đề với câu trả lời này: (1) Một lớp nhân vật POSIX "" không thể được sử dụng trực tiếp; nó phải được đặt trong một tập hợp các dấu ngoặc vuông khác, ví dụ: '[[: alnum:]] +'. Nhưng đó là học tập vì .NET không hỗ trợ chúng (thậm chí không ở dạng khác, như '\ p {Alnum}' của Java). (2) '\ w', giống như tất cả các ký hiệu lớp ký tự (' \ s', '\ d', v.v.), khớp chính xác với một chữ cái, vì vậy bạn nên sử dụng' \ w + '. (3) Bạn không cho phép khoảng trắng giữa các thẻ. –

+0

@Alan: Cảm ơn bạn đã sửa! Nhân tiện, "khoảng trắng" trong Emacs là gì? '\ s' dường như không hoạt động ... –

+1

Tôi không sử dụng Emacs, nhưng theo [this] (http://www.emacswiki.org/emacs/RegularExpression), đó là' \ s-'. Bản thân '\ s' không khớp với bất kỳ thứ gì; nó chỉ đánh dấu nhân vật sau đây là đặc biệt. –

1

Hãy thử mô hình này: ^([a-zA-Z0-9]+,?\s*)+$

Tôi đã thử nghiệm nó với trường hợp của bạn, cũng như chỉ là một số duy nhất "123". Tôi không biết nếu bạn sẽ luôn luôn có một dấu phẩy hay không.

Các [a-zA-Z0-9]+ nghĩa trận đấu 1 hoặc nhiều các biểu tượng này Các ,? nghĩa trận đấu là 0 hoặc 1 dấu phẩy (về cơ bản, dấu phẩy là không bắt buộc) Các \s* xử lý 1 hoặc nhiều khoảng trống sau dấu phẩy và cuối cùng là ngoài + nói trận đấu 1 hoặc nhiều mẫu.

này cũng sẽ phù hợp 123 123 abc (không dấu phẩy) mà có thể là một vấn đề này cũng sẽ phù hợp 123, (kết thúc bằng một dấu phẩy) mà có thể là một vấn đề.

0

Bạn dường như thiếu sự lặp lại. Làm thế nào về:

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

Tôi không chắc chắn làm thế nào bạn muốn bày tỏ rằng trong VB.Net, nhưng bằng 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 
>>>> 

Bạn có thể sử dụng phím tắt thay vì liệt kê các phần [a-zA-Z0-9 ], nhưng điều này có lẽ dễ hiểu hơn.

Phân tích những điểm nổi bật:

  • [a-zA-Z0-9 ]+: chụp một hoặc nhiều (nhưng không phải không) của các dãy niêm yết, và không gian.
  • (?:[...]+,)*: Trong dấu ngoặc đơn không bắt, khớp một hoặc nhiều ký tự, cộng với dấu phẩy ở cuối. So khớp các chuỗi đó bằng 0 hoặc nhiều lần. Việc chụp lần không cho phép không có dấu phẩy.
  • [...]+: nắm bắt ít nhất một trong số này. Điều này không bao gồm dấu phẩy. Điều này là để đảm bảo rằng nó không chấp nhận dấu phẩy. Nếu một dấu phẩy dấu là chấp nhận được, sau đó biểu thức là dễ dàng hơn: ^[a-zA-Z0-9 ,]+
+0

Điều này cho phép không gian ở bất cứ đâu, vì vậy nó cũng sẽ khớp với 'abc 123, fo o bar' '. Có lẽ đó là chấp nhận được với OP, nhưng tôi sẽ kéo không gian ra khỏi các lớp nhân vật. –

+0

@Alan điểm tốt. OP không giải quyết được không gian nào cả nhưng cho phép họ trong các ví dụ. Các regex có thể loại bỏ các không gian hiện có và thêm không gian tùy chọn (không gian sao) trước và sau dấu phẩy. – markets

1

Vâng, khi bạn muốn bắt dấu phẩy tách ra điều đó một dấu phẩy ở cuối là không quy phạm pháp luật, và những điều phù hợp để $LONGSTUFF, bạn phải lặp lại $LONGSTUFF:

$LONGSTUFF(,$LONGSTUFF)* 

Nếu $LONGSTUFF thực sự dài và chứa dấu phẩy lặp đi lặp lại các mặt hàng riêng của mình vv, nó có thể là một ý tưởng tốt để không xây dựng regexp bằng tay và thay vào đó dựa vào một máy tính để làm điều đó cho bạn u, ngay cả khi nó chỉ thông qua nối chuỗi. Ví dụ, tôi chỉ muốn xây dựng một biểu thức chính quy để xác nhận tham số CPUID của XEN configuration file, thuộc loại ['1:a=b,c=d','2:e=f,g=h']. Tôi ... tin rằng điều này chủ yếu là phù hợp với dự luật: (khoảng trắng bất kể!)

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

Xin lưu ý rằng RE ở trên có một vài vấn đề, bao gồm nhưng không giới hạn ở việc thiếu sự hỗ trợ khoảng trắng và độ nhạy trường hợp, điều đó khiến cho sản phẩm không xứng đáng. Các phiên bản cố định là khá nhiều lâu hơn và sau đó bạn sẽ bắt đầu thiếu điểm của câu trả lời. Nó chỉ là một ví dụ về cách xử lý các trường hợp phức tạp hơn một cách an toàn. – badp

+0

Tôi đã không kết thúc bằng cách sử dụng regexp đó - vì vậy [đây là toàn bộ shebang] (https://gist.github.com/badp/6353579) – badp

Các vấn đề liên quan