Biểu thức chính quy ngắn nhất không thể so sánh được


59

Nhiệm vụ của bạn là viết biểu thức chính quy hợp lệ ngắn nhất mà không có chuỗi nào có thể khớp, bao gồm chuỗi trống.

Đệ trình phải có mẫu này ("ký hiệu theo nghĩa đen"):

/pattern/optional-flags

Chiến thắng regrec ngắn nhất. Kích thước regrec được tính bằng ký tự. (bao gồm cả dấu gạch chéo và cờ)

Vui lòng giải thích cách thức hoạt động của bạn (nếu nó không tầm thường)

Cảm ơn, và chúc vui vẻ!


Điều này truyền cảm hứng cho một câu hỏi từ tôi. Tôi sẽ đợi một vài ngày mặc dù. Đừng muốn 2 câu hỏi regex hoạt động cùng một lúc
Cruncher

13
"Hợp lệ" theo việc thực hiện nào? Tôi vừa tìm thấy một điều thú vị mà Perl vẫn ổn (và điều đó hợp lệ theo ngữ pháp RE duy nhất tôi có thể tìm thấy , nhưng mô-đun re của grep và Python từ chối.
Josh Caswell

1
Có, phương ngữ nào của regex? Có rất nhiều cái khác nhau.
hà mã

1
Nhưng còn tên của Chủ tịch thì sao? xkcd.com/1313
Carl Witthoft

@CarlWitthoft Bạn cần phải là một chương trình để tham gia cuộc thi đó: codegolf.stackexchange.com/q/17718/2180
boothby

Câu trả lời:


53

6 ký tự

Theo dõi câu trả lời của primo và Peter Taylor, và một gợi ý từ man perlre:

/(?!)/

Regex tương thích perl này khớp với một chuỗi rỗng không được theo sau bởi một chuỗi rỗng khác.


+1 - Đây có lẽ là câu trả lời ngắn nhất có thể mang theo rộng rãi (cùng với /x\by/, nhưng nếu tôi thực sự phải sử dụng một biểu thức chính tả như thế này - vì bất kỳ lý do gì - thì câu trả lời này cũng là câu trả lời rõ ràng nhất)
Martin Ender

@ m.buettner: Cảm ơn. Primo /(*FAIL)/có lẽ rõ ràng hơn, mặc dù. (Và thực sự man perlređã cho nó đi bằng cách đề cập rằng mỏ của tôi thực sự mở rộng ra bên trong của anh ấy.)
Nate Eldredge

/(*FAIL)/không phải là di động mặc dù. Và ngay cả trong Perl, tôi nghĩ đó là một tính năng tối nghĩa hơn là một cái nhìn tiêu cực.
Martin Ender

3
Bạn có được cái nhìn trong hầu hết tất cả các hương vị phổ biến (lấy cảm hứng từ Perl) ngày nay, trong khi tôi chưa bao giờ thấy những động từ điều khiển này ở bất cứ đâu ngoài Perl.
Martin Ender

1
Trong thực tế, tài liệu Perl (và -Mre=debug) nói rằng (?!)được tối ưu hóa (*FAIL)bằng trình tối ưu hóa regex Perl ( OPFAILtheo -Mre=debug). Ngoài ra, tôi không nghĩ rằng tôi đã thấy (*FAIL)bên ngoài Perl 5 (và Perl 6, nơi nó được gọi là <!>).
Konrad Borowski

39

8 ký tự

/(?=a)b/

Chúng tôi yêu cầu một chuỗi chứa một ký tự là cả hai abrõ ràng là không thể.


19
/(?!x)x/thậm chí trông còn bất khả thi hơn ;-)
Howard

@PeterTaylor ở đâu?
o0 '.

@Lohoris, ở đâu?
Peter Taylor

@PeterTaylor anh ấy đã đặt những quy tắc vô lý mà bạn nói đến ở đâu, tôi không thể tìm thấy chúng.
o0 '.

7
Các bạn, xin lỗi vì đã tính tôi đã chọn, tôi nghĩ việc bao gồm các dấu gạch chéo sẽ đơn giản hơn vì các cờ tùy chọn có thể xuất hiện sau chúng.
xem

31

5 ký tự

Không giống như tất cả những người lạm dụng $^... điều này thực sự hoạt động trong Perl:

/V\A/

\A khớp với phần đầu của chuỗi.


Nó hoạt động với ^quá.
Tomas


28

8 ký tự

/\w\b\w/

Một ranh giới từ ( \b) được bao quanh bởi các ký tự 'từ' ( \w- một trong [_a-zA-Z0-9]). Không thể so sánh được vì một trong các ký tự đứng trước hoặc theo một ranh giới từ phải là ký tự không phải là từ.

Nhân tiện: điều này tương tự như biểu thức không thể so sánh được

/\W\b\W/

trong đó \Wcó nghĩa là ký tự không 'từ'.


Đây là 8 ký tự theo các quy tắc của cuộc thi, bởi vì các dấu gạch chéo /được tính. Xem mục của OP, ví dụ . Đó là một mục tuyệt vời, mặc dù!
Josh Caswell

Nó cũng có thể là một người chiến thắng (hoặc gắn liền với mục của Peter Taylor ), do các vấn đề phụ thuộc vào việc thực hiện với một số mục ngắn hơn!
Josh Caswell

Rất thanh lịch! Tôi nghĩ rằng phải có một cái gì đó như thế này!
Tomas

22

4 ký tự

/$a/

tìm kiếm "a" sau khi kết thúc chuỗi.

hoặc là

/a^/

tìm kiếm trước khi bắt đầu chuỗi.


20
Tại sao đăng câu hỏi nếu bạn biết rằng có một giải pháp hai char?
Peter Taylor

3
@Howard: Điều đó khớp với một chuỗi trống: jsfiddle.net/RjLxJ
Chương

10
Tại sao tôi luôn tìm thấy những vấn đề này sau khi một giải pháp không thể đánh bại được cung cấp :(
Cruncher

43
-1: Đặt ^$ở vị trí "bất hợp pháp" chỉ khiến chúng bị coi là những nhân vật bình thường. Ví dụ đầu tiên của bạn phù hợp với nghĩa đen $atrong sedvà có thể các chương trình khác.
Ben Jackson

2
@Ben Jackson, điều đó không đúng với POSIX EREs. Hãy thử echo 'a^b' | grep 'a^b'so với echo 'a^b' | grep -E 'a^b'. Kiểm tra neo
9,9.9

21

5 ký tự

/$.^/

/$^/ sẽ khớp với một chuỗi rỗng, trong khi yêu cầu một ký tự ở giữa sẽ không.


6
Điều này không may khớp "$a^"(hoặc bất cứ thứ gì thay thế 'a') trong Perl ( và có thể là sed ). Vẫn là một trong những tốt đẹp!
Josh Caswell

@JoshCaswell: Tôi đoán perl có thể hiểu $.là biến số dòng hiện tại. Mà có thể trống, trong trường hợp này sẽ được /^/.
MvG

Một ký tự 'giữa' chỉ có nghĩa là một chuỗi một ký tự.
JWG

3
@jwg nhận thấy sự hoán đổi ^$
mniip

Tôi đã thử mẫu '$^'với grep, nhưng không may là nó khớp với chuỗi '$^'. Thông minh grep.
joeytwiddle

19

9 ký tự

Tôi không chắc nhưng /[^\S\s]/sẽ không thể so sánh được vì nó không có nghĩa là bất kỳ nhân vật nào, mà ít nhất là một trong số họ.


Bạn không cần +.
Peter Taylor

10
/ [^ \ S \ s] / = 9 ký tự
xem

19

6 ký tự

Tôi nghĩ rằng regex này tôi đã thực hiện sẽ hoạt động:

/\b\B/

Nó khớp với một ranh giới từ ( \b) không phải là một ranh giới từ ( \B). Tôi thực sự phải giải thích điều này với bạn?


không phải cái này tìm kiếm một ranh giới từ theo sau là một ranh giới không từ?
grexter89

1
@ grexter89 Có, nhưng họ không thể có bất kỳ ký tự nào ở giữa. tức là Ranh giới và không biên phải chiếm cùng một không gian.
Chàng trai với chiếc mũ

2
Tôi thích cái này. Nắm bắt tốt.
primo

18

4 ký tự

(Chỉ hương vị ECMAScript)

/[]/

Trong các hương vị khác, đây không phải là một lớp ký tự hợp lệ ( ]sẽ được coi là một ký tự trong lớp, vì vậy biểu thức không hợp lệ, vì lớp này không bao giờ bị đóng), nhưng tiêu chuẩn ECMAScript chấp nhận các lớp ký tự trống. Vì nó là một lớp nó để phù hợp với một nhân vật (vì vậy chuỗi rỗng không phù hợp), nhưng vì không phải là một nhân vật duy nhất được bao gồm không có nhân vật thực tế sẽ phù hợp với một trong hai.


Điều này sẽ không khớp với một chuỗi trống mặc dù bạn nói nó phải khớp với một ký tự? Hoặc bạn có nghĩ rằng điều này là bất hợp pháp : /[]{0}/. (. Ps mặc dù câu trả lời của riêng tôi một phần trông giống như bạn, tôi thực sự đọc của bạn sau khi viết tôi.)
nl-x

@ nl-x dán cái này vào bảng điều khiển của trình duyệt của bạn : /[]/.test(""). nó trả về sai một lớp ký tự không bao giờ có thể khớp với một chuỗi rỗng, ngay cả khi nó không chứa các ký tự (tôi tưởng tượng chúng được triển khai như "NẾU ký tự tiếp theo trong chuỗi là một trong những chuỗi được liệt kê, khớp; ELSE thất bại"). /[]{0}/là hợp pháp (trong ECMAScript) và không khớp với chuỗi trống ... tuy nhiên, tôi không chắc điều đó có liên quan đến câu trả lời của tôi như thế nào.
Martin Ender


@Nakilon tất nhiên rồi. Ruby không thực hiện hương vị ECMAScript.
Martin Ender

15

6 ký tự

/b++b/

Bộ định lượng sở hữu tìm kiếm càng nhiều b càng tốt, sau đó thêm 1 b. 6 ký tự nhưng điểm cho đối xứng?


Hả ... tôi vừa học được một tính năng mới. Rõ ràng, kỹ năng regex của tôi đã lỗi thời. Cảm ơn và +1.
Ilmari Karonen

8

6 ký tự

/(\1)/

Không phải là một người chiến thắng, nhưng tôi nghĩ đó là niềm vui. grep và Python đều dùng barf trên cái này, nhưng Perl có vẻ ổn với nó.

Có vẻ như rất phụ thuộc vào việc thực hiện (điều này hầu như không đáng ngạc nhiên, vì sự kỳ lạ của nó). Bob báo cáo bên dưới rằng nó phù hợp với bất cứ điều gì trong công cụ regex của JavaScript.


Công cụ regex của .NET dường như chấp nhận nó.
Bob

Và nó luôn khớp (một chuỗi trống) bất kể đầu vào nào trên JS
Bob

8

Có thể một chút gian lận, nhưng Giáo

\0

Không thể so sánh được trong regex POSIX trong hầu hết tất cả, nếu không nói là tất cả. RE CƠ BẢN và RE EXTENDED RE, thậm chí.

Và POSIX RE không cần những dấu gạch chéo và cờ mà PCRE có.


+1 tốt !! Thật không may, duy nhất 0không hoạt động trong PERL. "0"=~0là sự thật ...
Tomas

\0ITYM duy nhất ? Có, hầu hết các triển khai perlre (1) và PCRE không sử dụng chuỗi C nhưng bộ đệm giới hạn kích thước, trong đó thủ thuật này sẽ không hoạt động, nhưng hầu hết các triển khai POSIX RE đều hoạt động trên chuỗi C.
mirabilos

5

5 ký tự

/^.^/

Khớp chuỗi bắt đầu bằng bất kỳ ký tự đơn nào trước khi chuỗi bắt đầu.


6
Cũng khớp với chuỗi".^"
boothby

@boothby: ngôn ngữ nào phù hợp? trong Python thì không. re.findall(r'^.^', '.^', re.DEBUG)
P̲̳x͓L̳

8
+1 để sử dụng toán tử manga (xem stackoverflow.com/questions/3618340/iêu )
nguyên mẫu

@boothby ^.là siêu nhân vật không theo nghĩa đen, cần phải thoát
P̲̳x͓L̳

1
Nó bị hỏng ở Perl. Câu hỏi này thực sự nên đặt ra một số quy tắc cơ bản về ngôn ngữ.
gian hàng

5

4 ký tự:

/.^/

Hoạt động với GNU grep 2.5.1 và egrep.


/.^/= 4 ký tự.
Alexey Popkov

Tại sao bạn cần //? những thứ đó không bắt buộc ở mọi nơi ;-)
RSFalcon7

Số /lượng dấu gạch chéo , xem câu hỏi ban đầu ("bao gồm dấu gạch chéo và cờ") và mục nhập của OP .
Alexey Popkov

đúng! Tôi nhớ đã đọc :(
RSFalcon7

Không, vì lý do tương tự như dưới đây: Thật ra, Mạnh ^ Chỉ chỉ đặc biệt nếu ở đầu mẫu. Bất kỳ ... ^ Sau bất cứ điều gì khác không cần phải thoát, vì vậy câu trả lời này là sai.
mirabilos

4

Perl 6 (5 ký tự)

/<!>/

Lạm dụng quy tắc sắp xếp (vì các biểu thức Perl 6 khác nhau và không tương thích với các biểu thức chính quy theo thiết kế), nhưng tôi không quan tâm. <!>quy tắc thông báo cho Perl 6 rằng regex không khớp.


4

6 byte

/(*F)/

Một tên viết tắt cho (*FAIL), được hỗ trợ bởi các công cụ regex tương thích perl. Cảm ơn @ HamZa đã chỉ ra điều này.

9 byte

/(*FAIL)/

Nên làm việc với bất kỳ công cụ regex nào hỗ trợ động từ cả. Tôi không tin điều này thực sự cần phải được đánh gôn thêm nữa.


1
Cái này hoạt động ra sao?
gian hàng

@boothby (*FAIL)là một động từ luôn luôn thất bại.
Primo

@primo bạn có thể chỉ cần sử dụng /(*F)/:)
HamZa

4

4 ký tự

/$./

Cần bất kỳ ký tự nào sau khi chuỗi kết thúc


Tương tự như hai cái còn lại, $chỉ đặc biệt ở phần cuối của mẫu.
mirabilos

3

4 ký tự có dấu gạch chéo 2 không có

Trong công cụ regex của ngôn ngữ TXR, một lớp ký tự trống không []khớp với ký tự và do đó không có chuỗi. Nó hành xử theo cách này bởi vì lớp nhân vật yêu cầu một nhân vật phù hợp, và khi nó trống, nó xác định rằng không có nhân vật nào có thể thỏa mãn nó.

Một cách khác là đảo ngược "tập hợp tất cả các chuỗi bao gồm cả regex trống" /.*/bằng cách sử dụng toán tử bổ sung : /~.*/. Phần bù của tập hợp đó không chứa chuỗi nào cả, và do đó không thể khớp với bất cứ thứ gì.

Đây là tất cả tài liệu trong trang người đàn ông:

   nomatch
          The  nomatch  regular  expression  represents  the empty set: it
          matches no strings at all, not even the empty string.  There  is
          no  dedicated  syntax  to  directly express nomatch in the regex
          language.  However, the empty character class []  is  equivalent
          to nomatch, and may be considered to be a notation for it. Other
          representations of nomatch are possible: for instance, the regex
          ~.* which is the complement of the regex that denotes the set of
          all possible strings, and thus denotes the empty set. A  nomatch
          has  uses;  for instance, it can be used to temporarily "comment
          out" regular expressions. The regex ([]abc|xyz) is equivalent to
          (xyz), since the []abc branch cannot match anything. Using [] to
          "block" a subexpression allows you to leave it  in  place,  then
          enable it later by removing the "block".

Dấu gạch chéo không phải là một phần của cú pháp regex mỗi se; chúng chỉ là dấu chấm câu phân định biểu thức chính tả trong ký hiệu biểu thức S. Nhân chứng:

# match line of input with x variable, and then parse that as a regex
#
$ txr -c '@x
@(do (print (regex-parse x)) (put-char #\newline))' -
ab.*c                               <- input from tty: no slashes.
(compound #\a #\b (0+ wild) #\c)    <- output: AST of regex

cảm ơn câu trả lời của bạn và xin lỗi một lần nữa cho việc đếm gạch chéo. Tôi nghĩ rằng sẽ dễ dàng hơn để bao gồm chúng nếu mọi người sử dụng cờ.
xem

1

6 ký tự

(hoặc 4, tùy thuộc vào cách bạn nhìn vào nó)

/{,0}/


Trong đó thực hiện regex này không đưa ra một lỗi?
Peter Taylor

Tôi chỉ kiểm tra nó bằng preg_match của PHP.
Tercy

1

Đây là một regex 5 char.

/[]+/

Nó phù hợp với một nhóm trống 1 hoặc nhiều lần.

BIÊN TẬP:

Đã xóa câu trả lời của tôi cho các hương vị khác:

/.{-1}/

Bất cứ điều gì không phải là số bên trong {} sẽ khớp với văn bản.

Cái này sẽ khớp với ". {- 1}"


Lưu ý rằng điều này chỉ hoạt động trong hương vị ECMAScript. Trong hầu hết (tất cả?) Những người khác, nó không phải là một biểu thức hợp lệ.
Martin Ender

Có phải nó không hợp lệ?
Wasi

@ Không giống với hương vị phù hợp với ECMAScript
Martin Ender

0

5 ký tự

Hy vọng điều này không có vẻ ngu ngốc: /[]+/


Không. Không phải là một regex hợp lệ.
Chàng trai với chiếc mũ

@RyanCarlson Nó hợp lệ và hợp pháp ... Ít nhất là trong Ecmascript.
nl-x

-1
/$^/

Một điều kết thúc trước khi nó bắt đầu ...


7
Khớp chuỗi rỗng (trong một số triển khai RE, dù sao).
Josh Caswell

1
Việc triển khai của bạn bị hỏng :)
simon

2
Tốt hơn hãy cho Guido biết .
Josh Caswell

7
Quan trọng hơn, như Ben Jackson đã chỉ ra , trong Perl, nơi mà nó không phù hợp "", nó không phù hợp với một chuỗi chứa hai ký tự chữ: "$^".
Josh Caswell

+1 Tôi chỉ muốn đăng cùng! @Josh, nó hoạt động trong PERL và nó không khớp với chuỗi rỗng! Bình luận của Ben bị hỏng, tôi trả lời nó.
Tomas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.