นิพจน์ทั่วไปที่ไม่สามารถจับคู่สั้นที่สุด


59

ภารกิจของคุณคือการเขียนนิพจน์ทั่วไปที่ถูกต้องสั้นที่สุดที่ไม่มีสตริงที่สามารถจับคู่ได้รวมสตริงว่าง

ส่งต้องมีแบบฟอร์มนี้ ("สัญกรณ์ตัวอักษร"):

/pattern/optional-flags

regexp ที่สั้นที่สุดชนะ ขนาด regexp ถูกนับเป็นตัวอักษร (รวมเครื่องหมายทับและธง)

โปรดอธิบายวิธีการใช้งาน regexp ของคุณ (หากไม่ใช่เรื่องเล็กน้อย)

ขอขอบคุณและขอให้สนุก!


นี่เป็นแรงบันดาลใจให้ฉัน ฉันจะรอไม่กี่วัน ไม่ต้องการให้คำถาม 2 regex ใช้งานในเวลาเดียวกัน
Cruncher

13
"ถูกต้อง" ตามการใช้งานใด ฉันได้พบเพียงหนึ่งที่น่าขบขัน Perl คือโอเคกับ (และที่ถูกต้องตามไวยากรณ์ RE เดียวที่ฉันสามารถหาแต่ที่ grep และโมดูลใหม่ ธ ปฏิเสธ.
จอชแคสเวล

1
ใช่ภาษาถิ่นใดของ regex มีมากมายหลายแบบ
hippietrail

1
แต่ชื่อของประธานาธิบดีล่ะ? xkcd.com/1313
Carl Witthoft

@CarlWitthoft คุณจะต้องเป็นโปรแกรมที่จะเข้าร่วมในการแข่งขัน: codegolf.stackexchange.com/q/17718/2180
บูธโดย

คำตอบ:


53

6 ตัวอักษร

ทำตามคำตอบของ Primo และ Peter Taylor และคำใบ้จากman perlre:

/(?!)/

regex ที่เข้ากันได้กับ Perl นี้จับคู่สตริงว่างที่ไม่ได้ตามด้วยสตริงว่างอื่น


+1 - นี่อาจเป็นคำตอบที่สั้นที่สุดที่พกพาได้อย่างกว้างขวาง (พร้อมด้วย/x\by/แต่ถ้าฉันต้องใช้ regex แบบนี้ด้วยเหตุผลใดก็ตาม - คำตอบนี้ก็ชัดเจนที่สุด)
Martin Ender

@ m.buettner: ขอบคุณ พรีโม่/(*FAIL)/อาจจะชัดเจนกว่า (และman perlreให้มันออกไปจริง ๆโดยการพูดถึงว่าผมขยายไปถึงภายในของเขาจริง ๆ )
เนทเอลเดรด

/(*FAIL)/ไม่ได้พกพาเหมือนกัน และแม้แต่ใน Perl ฉันคิดว่ามันเป็นคุณสมบัติที่คลุมเครือมากกว่า lookahead เชิงลบ
Martin Ender

3
คุณได้รับการมองในรสชาติที่เป็นที่นิยมเกือบทั้งหมดในวันนี้ในขณะที่ฉันไม่เคยเห็นกริยาควบคุมเหล่านี้ที่ใดก็ได้ แต่ใน Perl
Martin Ender

1
ในความเป็นจริงเอกสาร Perl (และ-Mre=debug) บอกว่าได้(?!)รับการปรับให้เหมาะสม(*FAIL)โดยเครื่องมือเพิ่มประสิทธิภาพ Perl regex ( OPFAILตาม-Mre=debug) นอกจากนี้ฉันไม่คิดว่าฉันเห็น(*FAIL)ด้านนอกของ Perl 5 (และ Perl 6 ซึ่งมันถูกเรียกว่า<!>)
Konrad Borowski

39

8 ตัวอักษร

/(?=a)b/

เราต้องการสตริงที่มีตัวละครที่ทั้งคู่aและbซึ่งเป็นไปไม่ได้แน่นอน


19
/(?!x)x/ดูมากยิ่งขึ้นไปไม่ได้ ;-)
ฮาวเวิร์ด

@PeterTaylor อยู่ที่ไหน
o0 '

@ โลริสที่ไหนอะไร
Peter Taylor

@ PeterTaylor เขาวางกฎที่ไร้สาระที่คุณพูดถึงไว้ที่ไหนฉันไม่พบมัน
o0 '

7
พวกฉันขอโทษสำหรับการนับที่ฉันเลือกฉันคิดว่ามันจะง่ายกว่าที่จะใส่เครื่องหมายทับเพราะธงเสริมที่สามารถตามมาได้
xem

31

5 ตัวอักษร

ไม่เหมือนทุกคนที่ใช้ในทางที่ผิด$และ^... มันใช้งานได้จริงใน Perl:

/V\A/

\A ตรงกับจุดเริ่มต้นของสตริง


มันทำงานด้วย^เช่นกัน
โทมัส


28

8 ตัวอักษร

/\w\b\w/

ขอบเขตของคำ ( \b) ที่ล้อมรอบด้วยอักขระ 'คำ' ( \w- หนึ่งใน[_a-zA-Z0-9]) มันไม่สามารถจับคู่กันได้เนื่องจากหนึ่งในตัวละครที่อยู่ก่อนหน้าหรือต่อจากขอบเขตของคำจะต้องเป็นตัวอักษรที่ไม่ใช่คำ

โดยวิธีการ: นี้จะคล้ายกับการแสดงออกที่ไม่ตรงกัน

/\W\b\W/

โดยที่\Wหมายถึงตัวอักษรที่ไม่ใช่คำ


นี่คือ 8 ตัวอักษรตามกฎของการแข่งขันเพราะเครื่องหมายทับ/จะถูกนับ ดูรายการของ OP ตัวอย่างเช่น มันเป็นรายการที่ยอดเยี่ยม แต่!
Josh Caswell

นอกจากนี้ยังอาจเป็นผู้ชนะ (หรือเชื่อมโยงกับรายการของ Peter Taylor ) เนื่องจากปัญหาการใช้งานขึ้นอยู่กับรายการสั้น ๆ บางส่วน!
Josh Caswell

สง่างามมาก! ฉันคิดว่าต้องมีอะไรแบบนี้!
โทมัส

22

4 ตัวอักษร

/$a/

ค้นหา "a" หลังจากสิ้นสุดสตริง

หรือ

/a^/

ค้นหาก่อนเริ่มต้นของสตริง


20
ทำไมโพสต์คำถามถ้าคุณรู้ว่ามีวิธีแก้ปัญหาสองตัว?
Peter Taylor

3
@Howard: ตรงกับสตริงว่าง: jsfiddle.net/RjLxJ
ProgramFOX

10
เหตุใดฉันจึงมักพบปัญหาเหล่านี้เสมอหลังจากมีวิธีแก้ไขปัญหาที่ไม่สามารถเอาชนะได้ :(
Cruncher

43
-1: การวาง^และ$ในตำแหน่ง "ผิดกฎหมาย" จะทำให้พวกมันถูกใช้เป็นตัวอักษรธรรมดา ตัวอย่างแรกของคุณตรงกับตัวอักษร$aในsedและอาจโปรแกรมอื่น ๆ
Ben Jackson

2
@ Ben Jackson นั่นไม่เป็นความจริงสำหรับ POSIX EREs ลองเทียบกับecho 'a^b' | grep 'a^b' echo 'a^b' | grep -E 'a^b'ลองดูAnchoring 9.4.9 ERE Expression
laindir

21

5 ตัวอักษร

/$.^/

/$^/ จะจับคู่สตริงว่างในขณะที่ต้องใช้อักขระในระหว่างจะไม่


6
น่าเสียดายที่การแข่งขันนี้"$a^"(หรืออะไรก็ตามที่แทนที่'a') ใน Perl ( และอาจจะไม่ดี ) ยังคงเป็นคนดี แต่!
Josh Caswell

@JoshCaswell: ฉันเดาว่า Perl อาจตีความ$.ว่าเป็นตัวแปรหมายเลขบรรทัดปัจจุบัน /^/ซึ่งอาจจะเป็นที่ว่างเปล่าซึ่งในกรณีนี้จะเป็น
MvG

ตัวอักษร 'ระหว่าง' เพียงแค่หมายถึงสายอักขระหนึ่งตัว
jwg

3
@jwg สังเกตเห็นการแลกเปลี่ยน^และ$
mniip

ฉันพยายามรูปแบบ'$^'กับ grep '$^'แต่โชคร้ายที่มันจับคู่สตริง Smartass grep
joeytwiddle

19

9 ตัวอักษร

ฉันไม่แน่ใจ แต่/[^\S\s]/ควรจะไม่สามารถจับคู่ได้เพราะมันหมายถึงตัวละครใด ๆ แต่อย่างน้อยหนึ่งในนั้น


+คุณไม่จำเป็นต้อง
Peter Taylor

10
/ [^ \ S \ s] / = 9 ตัวอักษร
xem

19

6 ตัวอักษร

ฉันคิดว่า regex นี้ฉันทำจะทำงาน:

/\b\B/

มันตรงกับขอบเขตของคำ ( \b) ที่ไม่ใช่ขอบเขตของคำ ( \B) Impos ใด - ฉันต้องอธิบายเรื่องนี้ให้คุณฟัง


คนนี้ไม่ได้ค้นหาคำศัพท์หรือไม่ตามด้วยคำที่ไม่ใช่ขอบเขต?
grexter89

1
@ grexter89 ใช่ แต่พวกเขาไม่สามารถมีตัวละครใด ๆ ในระหว่าง เช่นขอบเขตและไม่ใช่ขอบเขตจะต้องครอบครองพื้นที่เดียวกัน
ผู้ชายกับหมวก

2
ฉันชอบอันนี้ จับดี.
primo

18

4 ตัวอักษร

(ECMAScript รสเท่านั้น)

/[]/

ในรสชาติอื่น ๆ นี่ไม่ใช่คลาสอักขระที่ถูกต้อง ( ]จะถือว่าเป็นอักขระในคลาสดังนั้นนิพจน์ไม่ถูกต้องเนื่องจากคลาสไม่เคยปิด) แต่มาตรฐาน ECMAScript ยอมรับคลาสอักขระว่างเปล่า เพราะมันเป็นชั้นเรียนมันมีเพื่อให้ตรงกับตัวอักษร (เพื่อสตริงว่างไม่ตรงกัน) แต่เนื่องจากไม่ได้เป็นตัวเดียวจะรวมถึงไม่มีตัวละครที่เกิดขึ้นจริงจะตรงกับทั้ง


สิ่งนี้จะไม่ตรงกับสตริงว่างแม้ว่าคุณจะบอกว่ามันจะต้องตรงกับตัวละคร? /[]{0}/หรือคุณคิดว่านี่เป็นสิ่งผิดกฎหมาย: (. Ps แม้ว่าคำตอบของตัวเองบางส่วนมีลักษณะเช่นเดียวกับคุณที่จริงผมอ่านของคุณหลังจากที่เขียนเหมือง.)
NL-x

@ nl-x วางสิ่งนี้ลงในคอนโซลของเบราว์เซอร์ของคุณ: /[]/.test(""). มันกลับเท็จ คลาสตัวละครไม่สามารถจับคู่สตริงว่างแม้ว่ามันจะไม่มีตัวอักษร (ฉันคิดว่ามันจะถูกนำมาใช้เช่น "ถ้าอักขระต่อไปในสตริงเป็นหนึ่งในรายการที่ตรงกับการจับคู่; ELSE ล้มเหลว") /[]{0}/ถูกต้องตามกฎหมาย (ใน ECMAScript) และตรงกับสตริงว่าง ... แต่ฉันไม่แน่ใจว่าเกี่ยวข้องกับคำตอบของฉันอย่างไร
Martin Ender

Fails in Ruby 2.0
Nakilon

@Nakilon แน่นอนมันทำ Ruby ไม่ได้ใช้รสชาติ ECMAScript
Martin Ender

15

6 ตัวอักษร

/b++b/

Possessive quantifier นั้นมองหา b มากที่สุดเท่าที่จะเป็นไปได้และอีก 1 อัน 6 ตัวอักษร แต่ชี้ไปที่สมมาตร?


อืม ... ฉันเพิ่งเรียนรู้คุณลักษณะใหม่ เห็นได้ชัดว่าทักษะ regex ของฉันล้าสมัย ขอขอบคุณและ +1
Ilmari Karonen

8

6 ตัวอักษร

/(\1)/

ไม่ใช่ผู้ชนะ แต่ฉันคิดว่ามันสนุก grep และ Python ทั้งคู่ใช้ barf กับอันนี้ แต่ Perl ดูเหมือนจะโอเคกับมัน

ดูเหมือนจะขึ้นอยู่กับการนำไปใช้มาก (ซึ่งแทบจะไม่น่าแปลกใจเลยเพราะมีความแปลก) บ็อบรายงานด้านล่างว่าตรงกับสิ่งใดในเอนจิน regex ของ JavaScript


เอนจิ้น regex ของ. NET ดูเหมือนว่าจะยอมรับ
บ๊อบ

และมันจะจับคู่เสมอ (สตริงว่าง) ไม่ว่าจะป้อนข้อมูลใดใน JS
Bob

8

อาจเป็นการโกง แต่ ...

\0

…ไม่สามารถเทียบเคียงได้ในPOSIX regexในแทบทุกการติดตั้งใช้งาน RE ขั้นพื้นฐานและการขยาย RE แม้

และ POSIX RE ไม่จำเป็นต้องใช้เครื่องหมายทับที่น่ารำคาญและตั้งค่าสถานะ PCRE


+1 ดี !! น่าเสียดายที่คนเดียว0ไม่ทำงานใน PERL "0"=~0เป็นความจริง ...
Tomas

\0ITYM แต่เพียงผู้เดียว ใช่การปรับใช้perlre (1)และ PCRE ส่วนใหญ่ไม่ได้ใช้สตริง C แต่บัฟเฟอร์ที่มีขนาด จำกัด ซึ่งเคล็ดลับนี้จะไม่ทำงาน แต่การใช้ POSIX RE ส่วนใหญ่ทำงานบนสตริง C
mirabilos

5

5 ตัวอักษร

/^.^/

จับคู่สตริงที่ขึ้นต้นด้วยอักขระเดี่ยวใด ๆ ก่อนที่จะเริ่มต้นสตริง


6
นอกจากนี้ยังตรงกับสตริง".^"
บูธโดย

@boothby: ภาษาใดที่ตรงกัน? ใน Python ไม่ได้ re.findall(r'^.^', '.^', re.DEBUG)
P̲̳x͓L̳

8
+1 สำหรับการใช้ตัวดำเนินการมังงะ (ดูstackoverflow.com/questions/3618340/… )
ต้นแบบ

@boothby ^และ.metacharacters ไม่ใช่ตัวอักษรที่ต้องหลบหนี
P̲̳x͓L̳

1
มันหักด้วย Perl คำถามนี้ควรตั้งกฎพื้นฐานเกี่ยวกับภาษา
Boothby

5

4 ถ่าน:

/.^/

ทำงานร่วมกับ GNU grep 2.5.1 และ egrep


/.^/= 4 ตัวอักษร
Alexey Popkov

ทำไมคุณต้องการ//? สิ่งเหล่านี้ไม่จำเป็นต้องใช้ทุกที่ ;-)
RSFalcon7

ห่อ slashes /นับดูที่คำถามเดิม ( "รวมถึงทับและธง") และรายการของ OP
Alexey Popkov

ขวา! ฉันพลาดการอ่าน :(
RSFalcon7

ไม่ด้วยเหตุผลเดียวกับที่อยู่ด้านล่าง: จริง ๆ แล้ว“ ^” นั้นพิเศษเฉพาะเมื่อเริ่มต้นของรูปแบบ “ ^” ใด ๆ หลังจากสิ่งอื่นไม่จำเป็นต้องถูกหลบหนีดังนั้นคำตอบนี้ผิด
mirabilos

4

Perl 6 (5 ตัวอักษร)

/<!>/

การละเมิดกฎ Sorta (เนื่องจาก Perl 6 regexes แตกต่างกันและไม่สามารถใช้ร่วมกับ stardard regexes ได้ด้วยการออกแบบ) แต่ฉันไม่สนใจ <!>กฎแจ้ง Perl 6 ว่า regex ไม่ตรงกัน


4

6 ไบต์

/(*F)/

ตัวย่อสำหรับ(*FAIL)สนับสนุนโดยเครื่องมือ regex ที่เข้ากันได้ perl ขอบคุณ@HamZa ที่ชี้เรื่องนี้ออกมา

9 ไบต์

/(*FAIL)/

ควรทำงานกับเอ็นจิ้น regex ใด ๆ ที่รองรับคำกริยาได้เลย ฉันไม่เชื่อว่านี่จะต้องตีกอล์ฟต่อไปอีก


1
มันทำงานอย่างไร
Boothby

@boothby (*FAIL)เป็นคำกริยาที่ล้มเหลวเสมอ
primo

@primo คุณอาจใช้/(*F)/:)
HamZa

4

4 ตัวอักษร

/$./

ต้องการอักขระใด ๆ หลังจากที่สตริงสิ้นสุด


ในทำนองเดียวกันกับอีกสองคน$เป็นพิเศษเฉพาะในตอนท้ายของรูปแบบ
mirabilos

3

4 ตัวอักษรที่มีเครื่องหมายทับ 2 โดยไม่มี

ในเอ็นจิน regex ของภาษา TXR คลาสอักขระว่างเปล่า[]ไม่ตรงกับอักขระดังนั้นจึงไม่มีสตริง มันจะทำงานแบบนี้เพราะคลาสตัวละครต้องมีการจับคู่ตัวละครและเมื่อมันว่างเปล่าก็ระบุว่าไม่มีตัวละครที่สามารถตอบสนองได้

อีกวิธีหนึ่งคือการกลับว่า "ชุดของสตริงทั้งหมดรวมทั้งที่ว่างเปล่า" regex ใช้ประกอบสมบูรณ์:/.*/ /~.*/ส่วนเสริมของชุดนั้นไม่มีสตริงเลยดังนั้นจึงไม่สามารถจับคู่สิ่งใด ๆ ได้

นี่คือเอกสารทั้งหมดใน man page:

   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".

เครื่องหมายทับไม่ได้เป็นส่วนหนึ่งของไวยากรณ์ regex ต่อ se; พวกเขาเป็นเพียงเครื่องหมายวรรคตอนที่ delimits regexes ในสัญกรณ์ S-expression พยาน:

# 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

ขอบคุณสำหรับคำตอบของคุณและขออภัยอีกครั้งสำหรับการนับสแลช ฉันคิดว่ามันจะง่ายกว่าถ้าหากมีคนใช้ธง
xem


1

นี่คือ 5 char regex

/[]+/

มันตรงกับกลุ่มที่ว่าง 1 หรือมากกว่านั้น

แก้ไข:

ลบคำตอบของฉันสำหรับรสชาติอื่น ๆ :

/.{-1}/

สิ่งใดก็ตามที่ไม่ใช่ตัวเลขภายใน {} จะตรงกับข้อความ

อันนี้จะตรงกับ ". {- 1}"


โปรดทราบว่าสิ่งนี้ใช้ได้ใน ECMAScript รสเท่านั้น ในที่อื่น ๆ (ทั้งหมด?) ไม่ใช่นิพจน์ที่ถูกต้อง
Martin Ender

มันไม่ถูกต้องเหรอ?
Wasi

@ ไม่ได้อยู่ในรสชาติที่สอดคล้องกับ ECMAScript
Martin Ender

0

5 ตัวอักษร

หวังว่านี่จะไม่ใช่เสียงโง่ ๆ : /[]+/


Nope ไม่ใช่ regex ที่ถูกต้อง
The Guy with The Hat

@RyanCarlson มันถูกต้องและถูกกฎหมาย ... อย่างน้อยก็ใน Ecmascript
nl-x

-1
/$^/

สิ่งที่จบลงก่อนที่จะเริ่ม ...


7
ตรงกับสตริงที่ว่างเปล่า (ในการใช้งาน RE บางอย่าง anyways)
Josh Caswell

1
การใช้งานของคุณเสีย :)
simon

2
ดีกว่าปล่อยให้กุยรู้
Josh Caswell

7
ที่สำคัญเป็นเบนแจ็คสันชี้ให้เห็นใน Perl ที่มันไม่ตรงกับ""มันไม่"$^"ตรงกับสตริงที่มีทั้งสองตัวละครตัวอักษร:
Josh Caswell

+1 ฉันแค่ต้องการโพสต์เดียวกัน! @ จอชมันใช้งานได้ใน PERL และมันไม่ตรงกับสตริงว่าง! ความเห็นของเบ็นฉันตอบแล้ว
โทมัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.