Hương vị PCRE, 261 289 210 184 127 109 71 53 51 44 40 byte
Vâng, nó là có thể!
<^<()(?R){2}>\z|\1\Q^<()(?R){2}>\z|\1\Q>
Hãy thử nó ở đây. (Nhưng /
được hiển thị là dấu phân cách trên Regex101.)
Vui lòng không thực hiện các chỉnh sửa (cập nhật) không cần thiết trên trang Regex101. Nếu chỉnh sửa của bạn không thực sự liên quan đến việc cải thiện, thử hoặc kiểm tra biểu thức chính quy này, bạn có thể rẽ nhánh hoặc tạo bản mới từ trang chủ của họ .
Phiên bản hoạt động chính xác hơn trên Regex101 (44 byte):
/^\/()(?R){2}\/\z|\1\Q^\/()(?R){2}\/\z|\1\Q/
Hãy thử nó ở đây.
Điều này đơn giản hơn nhiều so với phiên bản gốc và hoạt động giống như một chiếc quine truyền thống. Nó cố gắng xác định một chuỗi mà không sử dụng nó và sử dụng nó ở một nơi khác. Vì vậy, nó có thể được đặt rất gần với một đầu của biểu thức chính quy, để giảm số lượng ký tự cần nhiều ký tự để xác định mẫu phù hợp và lặp lại nhiều lần hơn.
Giải thích:
\Q^\/()(?R){2}\/\z|\1\Q
phù hợp với chuỗi ^\/()(?R){2}\/\z|\1\Q
. Điều này sử dụng một cách giải quyết mà \Q...\E
không cần phải đóng, và các dấu phân cách không được giải quyết hoạt động \Q
. Điều này làm cho một số phiên bản trước chỉ hoạt động trên Regex101 chứ không phải cục bộ. Nhưng may mắn thay, phiên bản mới nhất đã hoạt động và tôi đã sử dụng thêm một số byte bằng cách này.
\1
trước khi \Q
khớp với nhóm bị bắt 1. Vì nhóm 1 không tồn tại trong tùy chọn này, nên nó chỉ có thể khớp trong các cuộc gọi đệ quy. Trong các cuộc gọi đệ quy, nó khớp với các chuỗi rỗng.
(?R){2}
gọi toàn bộ regex đệ quy hai lần, khớp ^\/()(?R){2}\/\z|\1\Q
cho mỗi lần.
()
không làm gì ngoài việc bắt một chuỗi rỗng vào nhóm 1, cho phép tùy chọn khác trong các cuộc gọi đệ quy.
^\/()(?R){2}\/\z
phù hợp (?R){2}
với dấu phân cách được thêm vào, từ đầu đến cuối. Các \/
trước khi cuộc gọi đệ quy cũng chắc chắn rằng tùy chọn này tự nó không phù hợp trong các cuộc gọi đệ quy, bởi vì nó sẽ không được vào đầu của chuỗi.
51 byte đã đóng \Q...\E
:
/\QE\1|^\/(\\)Q(?R){2}z\/\E\1|^\/(\\)Q(?R){2}z\/\z/
Hãy thử nó ở đây.
Phiên bản gốc, 188 byte
Cảm ơn Martin Büttner vì đã chơi golf khoảng 100 byte!
/^(?=.{173}\Q\2\)){2}.{11}$\E\/\z)((?=(.2.|))\2\/\2\^\2\(\2\?=\2\.\2\{173}\2\\Q\2\\2\2\\\2\)\2\)\2\{2}\2\.\2\{11}\2\$\2\\E\2\\\2\/\2\\z\2\)\2\(\2\(\2\?=\2\(\2\.2\2\.\2\|\2\)\2\)){2}.{11}$/
Hãy thử nó ở đây.
Hoặc 210 byte mà không có \Q...\E
:
/^(?=.{194}\\2\\.\)\{2}\.\{12}\$\/D$)((?=(.2.|))\2\/\2\^\2\(\2\?=\2\.\2\{194}\2\\\2\\2\2\\\2\\\2\.\2\\\2\)\2\\\2\{2}\2\\\2\.\2\\\2\{12}\2\\\2\$\2\\\2\/D\2\$\2\)\2\(\2\(\2\?=\2\(\2\.2\2\.\2\|\2\)\2\)){2}.{12}$/D
Hãy thử nó ở đây.
Phiên bản mở rộng:
/^(?=.{173}\Q\2\)){2}.{11}$\E\/\z) # Match things near the end.
((?=(.2.|)) # Capture an empty string or \2\ into group 2.
\2\/\2\^\2\(\2\?=\2\.\2\{173}\2\\Q\2\\2\2\\\2\)\2\)\2\{2}\2\.
\2\{11}\2\$\2\\E\2\\\2\/\2\\z\2\) # 1st line escaped.
\2\(\2\(\2\?=\2\(\2\.2\2\.\2\|\2\)\2\) # 2nd line escaped.
){2}
.{11}$/x
Các phần mở rộng thích (?=
và \1
đã làm cho các biểu thức được gọi là "thông thường" không còn thường xuyên, điều này cũng làm cho các quine có thể. Backreference không thường xuyên, nhưng nhìn là được.
Giải trình:
- Tôi sử dụng
\2\
thay thế \
để thoát khỏi các nhân vật đặc biệt. Nếu \2
khớp với chuỗi trống, \2\x
(nơi x
là một ký tự đặc biệt) khớp với x
chính nó. Nếu \2
phù hợp \2\
, \2\x
phù hợp với một người thoát. \2
trong hai trận đấu của nhóm 1 có thể khác nhau về regex. Trong lần đầu tiên \2
phải khớp với chuỗi trống và lần thứ hai \2\
.
\Q\2\)){2}.{11}$\E\/\z
(dòng 1) khớp với 15 ký tự từ cuối. Và .{11}$
(dòng 7) khớp với 11 ký tự ở cuối (hoặc trước một dòng mới). Vì vậy, mẫu ngay trước mẫu thứ hai phải khớp với 4 hoặc 3 ký tự đầu tiên trong mẫu thứ nhất, do đó \2\.\2\|\2\)\2\)
phải khớp ...\2\)
hoặc ...\2\
. Không thể có một dòng mới vì ký tự cuối cùng phải có )
. Và văn bản phù hợp không chứa văn bản khác )
trước văn bản ngoài cùng bên phải, vì vậy tất cả các ký tự khác phải nằm trong \2
. \2
được định nghĩa là (.2.|)
, vì vậy nó chỉ có thể được \2\
.
- Dòng đầu tiên làm cho toàn bộ biểu thức khớp chính xác với 188 ký tự vì mọi thứ đều có độ dài cố định. Hai lần của nhóm 1 khớp với 45 * 2 ký tự cộng với 29 lần
\2
. Và những thứ sau nhóm 1 khớp với 11 ký tự. Vì vậy, tổng độ dài của hai lần \2
phải chính xác là 3 ký tự. Biết \2
lần thứ hai dài 3 ký tự, lần đầu tiên phải trống.
- Tất cả mọi thứ ngoại trừ giao diện và
\2
là chữ trong nhóm 1. Với hai lần \2
được biết đến và một vài ký tự cuối cùng được biết từ dòng đầu tiên, regex này khớp chính xác với một chuỗi.
- Martin Büttner nảy ra ý tưởng sử dụng lookahead để chụp nhóm 2 và làm cho nó trùng lặp với phần quine. Điều này đã loại bỏ các ký tự không thoát theo cách thông thường giữa hai lần của nhóm 1 và giúp tránh mô hình khớp với chúng trong phiên bản gốc của tôi và đơn giản hóa regex rất nhiều.
Regex không thu hồi hoặc phản hồi, 85 byte
Ai đó có thể lập luận rằng các biểu thức với sự thu hồi hoặc phản hồi không phải là biểu thức "thông thường" thực sự. Nhưng các biểu thức chỉ có giao diện vẫn có thể chỉ khớp với các ngôn ngữ thông thường, mặc dù chúng có thể dài hơn nhiều nếu được biểu thị bằng các biểu thức thông thường truyền thống.
/(?=.*(\QE\\){2}z\/\z)^\/\(\?\=\.\*\(\\Q.{76}\E\\){2}z\/\z)^\/\(\?\=\.\*\(\\Q.{76}\z/
Hãy thử nó ở đây.
610 byte mà không có \Q...\E
(để được đánh gôn):
/^(?=.{610}$)(?=.{71}(\(\.\{8\}\)\?\\.[^(]*){57}\)\{2\}\.\{12\}\$\/D$)((.{8})?\/(.{8})?\^(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{610(.{8})?\}(.{8})?\$(.{8})?\)(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{71(.{8})?\}(.{8})?\((.{8})?\\(.{8})?\((.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{8(.{8})?\\(.{8})?\}(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\?(.{8})?\\(.{8})?\\(.{8})?\.(.{8})?\[(.{8})?\^(.{8})?\((.{8})?\](.{8})?\*(.{8})?\)(.{8})?\{57(.{8})?\}(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\{2(.{8})?\\(.{8})?\}(.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{12(.{8})?\\(.{8})?\}(.{8})?\\(.{8})?\$(.{8})?\\(.{8})?\/D(.{8})?\$(.{8})?\)(.{8})?\(){2}.{12}$/D
Hãy thử nó ở đây.
Ý tưởng là tương tự.
/^(?=.{610}$)(?=.{71}(\(\.\{8\}\)\?\\.[^(]*){57}\)\{2\}\.\{12\}\$\/D$)
((.{8})?\/(.{8})?\^(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{610(.{8})?\}(.{8})?\$(.{8})?\)
(.{8})?\((.{8})?\?=(.{8})?\.(.{8})?\{71(.{8})?\}
(.{8})?\((.{8})?\\(.{8})?\((.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{8(.{8})?\\(.{8})?\}
(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\?(.{8})?\\(.{8})?\\
(.{8})?\.(.{8})?\[(.{8})?\^(.{8})?\((.{8})?\](.{8})?\*(.{8})?\)(.{8})?\{57(.{8})?\}
(.{8})?\\(.{8})?\)(.{8})?\\(.{8})?\{2(.{8})?\\(.{8})?\}
(.{8})?\\(.{8})?\.(.{8})?\\(.{8})?\{12(.{8})?\\(.{8})?\}
(.{8})?\\(.{8})?\$(.{8})?\\(.{8})?\/D(.{8})?\$(.{8})?\)(.{8})?\(){2}.{12}$/D
Biểu thức chính quy cơ bản
Nếu lookahead không được phép, điều tốt nhất tôi có thể làm bây giờ là:
/\\(\\\(\\\\){2}/
phù hợp với
\\(\\\(\\
Nếu {m,n}
định lượng không được phép, điều đó là không thể bởi vì không có gì chỉ có thể khớp với một chuỗi, có thể khớp với một chuỗi dài hơn chính nó. Tất nhiên người ta vẫn có thể phát minh ra thứ gì đó giống như \q
chỉ khớp /\q/
và vẫn nói biểu thức với thông thường đó. Nhưng rõ ràng không có gì như thế này được hỗ trợ bởi các triển khai lớn.