ย้อนกลับ regex


27

ความท้าทาย

ให้ regex ที่ถูกต้อง, ส่งออก regex ที่ตรงกับชุดของสตริงเดียวกัน, แต่กลับด้าน

งาน

ความท้าทายนี้ใช้มากที่สุดในการดำเนินงาน regex พื้นฐาน: ^, $, ?, +, *, [], ,{} |ไม่มีสิ่งเช่นกลุ่มจับภาพหรือสิ่งที่ซับซ้อนใด ๆ สามารถหนีอักขระพิเศษได้

ตัวอย่างอินพุต / เอาต์พุต

หมายเหตุ: จะไม่มีการป้อนข้อมูลที่ไม่ถูกต้องและมีคำตอบที่เป็นไปได้หลายประการสำหรับการป้อนที่กำหนด!

Input      | Sample Output
-----------|-------------
abc        | cba
tuv?       | v?ut
a(b|c)     | (c|b)a
1[23]      | [23]1
a([bc]|cd) | (dc|[bc])a
^a[^bc]d$  | ^d[^bc]a$
x[yz]{1,2} | [yz]{1,2}x
p{2}       | p{2}
q{7,}      | q{7,}
\[c[de]    | [de]c\[
ab[c       | <output undefined>
a(?bc)     | <output undefined>
a[]]bc     | <output undefined>

การสาธิต

สาธิตการทำงานที่แสดงให้เห็นถึงอินพุต / เอาต์พุตที่ถูกต้อง นี่เป็นตรรกะเพิ่มเติมบางอย่างสำหรับการตรวจสอบอินพุตที่ไม่จำเป็นในคำตอบจริง พิจารณาอินพุตที่ไม่ถูกต้องว่าเป็นพฤติกรรมที่ไม่ได้กำหนด

ข้อมูลจำเพาะ

เพื่อความง่ายตัวละครพิเศษทุกตัวมีความหมายพิเศษหรือหนีไป นั่นคือไม่ได้เป็นช่วงที่ตัวละคร[[] [ช่วงความยาวมาจาก POSIX ERE มาตรฐาน นั่นคือ{n}, {n,}และ{n,m}ได้รับการสนับสนุน ช่วงตัวละคร[]และ[^]ได้รับการสนับสนุน เนื่องจากกฎเหล่านี้และเนื่องจากไม่มีการป้อนข้อมูลที่ไม่ถูกต้องคุณจะต้องคัดลอกเนื้อหาเหล่านี้ไปยังเอาต์พุตโดยตรงเท่านั้น ท้ายที่สุดความโลภก็ไม่สำคัญเช่นกันมันไม่สำคัญว่าเรจิสที่กลับด้านจะพบการจับคู่ที่แตกต่างกันก่อนมันแค่ต้องหาคู่ที่ตรงกันสำหรับสตริงชุดเดียวกัน

เกณฑ์การให้คะแนน

โปรแกรมที่เล็กที่สุดในหน่วยไบต์ (ยกเว้นการโกงเช่นคำขอเครือข่าย) จะชนะ โปรแกรมสามารถใช้ IO จริงหรือเพียงแค่กำหนดฟังก์ชั่น


1
เพราะไม่มีสิ่งใดที่?จะแนบไปกับ ลองพิมพ์/a(?bc)/ลงในคอนโซลของเบราว์เซอร์
TND

3
ดูดีตอนนี้ คุณอาจต้องการเพิ่มสิ่งที่ชอบ(^a|b)(c$|d)เป็นกรณีทดสอบ
Martin Ender

เราสามารถสมมติว่าอินพุตนั้นมีอักขระ ASCII ที่พิมพ์ได้หรือไม่ โดยเฉพาะอย่างยิ่งไม่มีอักขระตัวดึงบรรทัด
Martin Ender

1
เราควรพิจารณารอบคัดเลือกที่ใช้กับกลุ่มเช่น(a)?(b)+(b)+(a)?หรือไม่
kennytm

1
รายการการดำเนินการ regex ของคุณหายไป()ซึ่งใช้ในตัวอย่างของคุณ
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

คำตอบ:


7

เรตินา , 136 114 110 ไบต์

อ๋อใช่ฉันได้ยินมาว่าคุณชอบ regex ...

^
;
(T`^$`$^`;.
(.*);(\[(\\.|[^]])*]|\\.|.)([*+?]|{\d+(,|,\d+)?})?
$2$4!$1;
^\(!
) 
^\)(.*)!(.+?) 
($2$1
;$|!
<empty>

ในกรณีที่<empty>แสดงให้เห็นถึงบรรทัดต่อท้ายที่ว่างเปล่า เรียกใช้รหัสจากไฟล์เดียวกับ-sธง

... เมื่อคุณต้องการย้อนกลับ regex คุณควรใช้ regex เมื่อคุณต้องการใช้ regex คุณควรใช้ภาษาการเขียนโปรแกรมตาม regex

รหัสนี้อนุมานว่าการป้อนข้อมูลที่มีค่า;มิได้!ช่องว่างมิได้ ในขณะที่ฉันยอมรับว่าเป็นข้อสันนิษฐานที่แข็งแกร่งและไม่ถูกต้องคุณสามารถแทนที่ทั้งสามในรหัสด้วยอักขระที่ไม่สามารถพิมพ์ได้สามตัว (เช่น null bytes, ตัวอักษรระฆัง, <DEL>คุณตั้งชื่อ) และจะไม่มีผลต่อขนาดรหัสหรือฟังก์ชันการทำงาน เลย

ฉันจะเพิ่มคำอธิบายเมื่อฉันเล่นกอล์ฟเสร็จแล้ว


3
"ฉันต้อน * คุณนอน *"
lirtosiast

ฉันคิดว่ารหัสยังถือว่าสมมติว่า regex ไม่ได้มีอักขระบรรทัดใหม่ดิบ
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ โอ้จริงฉันอยู่ภายใต้สมมติฐานว่าจะไม่มีอักขระที่ไม่สามารถพิมพ์ได้ในอินพุต ฉันจะแก้ไขว่าเมื่อเราได้รับการชี้แจงจาก OP (หากตัวละครใด ๆ สามารถปรากฏขึ้นยังมีชุดค่าผสมบางอย่างที่จะไม่ปรากฏในสิ่งที่ท้าทายนี้พิจารณา regex ที่ถูกต้องเช่น]]]วิธีใดคำตอบนี้ไม่จำเป็นต้องแก้ไขมาก)
Martin Ender

เล่นกอล์ฟหลังจากผ่านไปหนึ่งปีไหม? : P
Okx

2

JavaScript ES6, 574 ไบต์

ฉันอาจลบvarคำสั่งไม่กี่คำ

R=e=>{for(var s=0,c=[],h=/(\?|\+|\{\d*,*\d*\}|\*)(\?*)/,t=0;t<e.length;t++)switch(s){case 0:switch(e[t]){case"\\":t++,c.push("\\"+e[t]);break;case"[":j=t,s=1;break;case"(":k=t,s=2;break;default:var l=e.search(h,t);(l>=t+1||0>l)&&c.push(l==t+1?e[t]+e.slice(t,e.length).match(h)[0]:e[t])}break;case 1:"\\"==e[t]?t++:"]"==e[t]&&(c.push(e.slice(j,t+1)+(e.search(h,t)==t+1?e.slice(t,e.length).match(h)[0]:"")),s=0);break;case 2:"\\"==e[t]?t++:")"==e[t]&&(a=R(e.slice(k+1,t)),c.push("("+a+")"),s=0)}c.reverse(),r=c;var i=c.length-1;return"^"==c[i]&&(r[i]="$"),"$"==c[0]&&(r[0]="^"),r.join``}}

JS ES6, ไม่ได้ทดสอบ, 559 ไบต์

จะทดสอบที่บ้าน

R=e=>{for(s=0,c=[],h=/(\?|\+|\{\d*,*\d*\}|\*)(\?*)/,t=0;t<e.length;t++)switch(s){case 0:switch(e[t]){case"\\":t++,c.push`\\${e[t]}`;break;case"[":j=t,s=1;break;case"(":k=t,s=2;break;default:l=e.search(h,t);(l>=t+1||0>l)&&c.push(l==t+1?e[t]+e.slice(t,e.length).match(h)[0]:e[t])}break;case 1:"\\"==e[t]?t++:"]"==e[t]&&(c.push(e.slice(j,t+1)+(e.search(h,t)==t+1?e.slice(t,e.length).match(h)[0]:"")),s=0);break;case 2:"\\"==e[t]?t++:")"==e[t]&&(a=R(e.slice(k+1,t)),c.push`(${a})`,s=0)}c.reverse(),r=c;i=c.length-1;return"^"==c[i]&&(r[i]="$"),"$"==c[0]&&(r[0]="^"),r.join``}}

JavaScript ES5, ไม่ได้รับการบันทึก, 961 ไบต์

function revRegex(str){
 var mode = 0;
 var oS = [];
 var post = /(\?|\+|\{\d*,*\d*\}|\*)(\?*)/;
 for(var i=0;i<str.length;i++){
  switch(mode){
   case 0: switch(str[i]){
    case "\\": i++; oS.push("\\"+str[i]); break;
    case "[": j=i; mode = 1; break;
    case "(": k=i; mode = 2; break;
    default:
     var pLoc = str.search(post,i);
     if(pLoc>=i+1||pLoc<0){ // current is not pLoc
      if(pLoc==i+1){
       oS.push(str[i] + str.slice(i,str.length).match(post)[0]);
      } else {
       oS.push(str[i]);
      }
     }
   }; break;
   case 1: if(str[i]=="\\") i++; else if(str[i]=="]"){oS.push

(str.slice(j,i+1)+(str.search(post,i)==i+1?str.slice

(i,str.length).match(post)[0]:""));mode = 0}; break;
   case 2: if(str[i]=="\\") i++; else if(str[i]==")")

{a=revRegex(str.slice(k+1,i));oS.push("("+a+")");mode = 

0};break;
  }
 }
 oS.reverse();
 r=oS;
 var l=oS.length-1;
 if(oS[l]=="^") r[l]="$";
 if(oS[0]=="$") r[0]="^";
 return r.join("");
}

5
ฮ่า ๆ คุณใช้ regex เพื่อย้อนกลับ regex: D
Kritixi Lithos

3
@ ΚριτικσιΛίθοςใช่ฉันไม่: D ผมจะใช้มันเพื่อแยก HTML ถ้าผม ...
Conor โอไบรอัน


1
@ CᴏɴᴏʀO'Bʀɪᴇɴฉันแจง HTML รหัสกับ regex แต่มีปัญหาร้ายแรงกับตัวอักษร Unicode
Abr001am

2
@ CᴏɴᴏʀO'Bʀɪᴇɴนี่เป็นอีกทางเลือกหนึ่ง: `code.replace (/.*/," trollolol ");
Kritixi Lithos

2

JavaScript ES6, 343 ไบต์

t=r=>(u="substr",T="(?:[+?*]|{\\d+(?:,\\d*)?})?)([^]*)",(c=r[0])=="(")?([n,s]=v(r[u](1)),[_,q,s]=s.match("^(\\)"+T),["("+n+q,s]):c==")"||c==null?["",r]:c=="^"?["^",r[u](1)]:c=="$"?["^",r[u](1)]:r.match("^("+/(?:\[(?:[^\]\\]|\\[^])*\]|[^[\\]|\\[^])/.source+T).slice(1);(v=r=>{var o="";do{[n,r]=t(r);o=n+o;}while(n&&r);return[o,r]})(prompt())[0]

รหัสดั้งเดิม (ฟังก์ชั่น แต่ไม่มีprompt):

function reverse(regex) {
    var out = "";
    do {
        // console.log("calling term");
        var [node, regex] = term(regex);
        // console.log("reverse: " + [node, regex]);
        out = node + out;
    } while (node && regex);
    return [out, regex];
}

function term(regex) {
    switch (regex[0]) {
        case "(":
            // console.log("calling reverse");
            var [node, sequel] = reverse(regex.substr(1));
            // console.log("term: " + regex + " / " + [node, sequel]);
            var [_, quantifier, sequel] = sequel.match(/^(\)(?:[+?*]|{\d+(?:,\d*)?})?)([^]*)/);
            return ["(" + node + quantifier, sequel];
        case ")":
        case void 0:
            return ["", regex];
        case "^":
            return ["$", regex.substr(1)];
        case "$":
            return ["^", regex.substr(1)];
        default:
            return regex.match(/^((?:\[(?:[^\]\\]|\\[^])*\]|[^[\\]|\\[^])(?:[+?*]|{\d+(?:,\d+)?})?)([^]*)/).slice(1);
    }
}

reverse("^\\(([The(){}*\\] ]{2,3}world\\\\(begin(ner|ning)?|ends*)+|Con\\|ti\\*n\\)ue...[^%\\[\\]()\\\\])$")[0]

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

รหัสอาจทำให้เกิดการวนซ้ำไม่สิ้นสุดในกรณีที่ไม่ถูกต้องเนื่องจากฉันไม่ได้ทดสอบพวกเขาใช้ประโยชน์จากข้อ "พฤติกรรมที่ไม่ได้กำหนด"


0

Python 3, 144 ไบต์

(อันนี้ไม่รองรับการคัดเลือกในกลุ่มที่ชอบ(a)+(b)*(cde)?)

import re;f=lambda x:''.join({e:e,'^':'$','$':'^','(':')',')':'('}[e]for e in re.findall(r'(?:\\.|\[(?:\\?.)+?\]|.)(?:[?+*]|\{.+?\})?',x)[::-1])

กรณีทดสอบ:

test_cases = [
    # Provided test cases
    r'abc',
    r'tuv?',
    r'a(b|c)',
    r'1[23]',
    r'a([bc]|cd)',
    r'^a[^bc]d$',
    r'x[yz]{1,2}',
    r'p{2}',
    r'q{7,}',
    r'\[c[de]',

    # Pathological cases
    r'a{3}b',
    r'(a)?(b)+',            # <-- currently failing!
    r'[\[]{5}[^\]]{6}',
    r'[\[]\]{7}',
    r'[\[\]]{8,9}',
    r'\(\)\^\$',

    # Undefined cases
    r'ab[c',
    r'a(?bc)',
    r'a[]]bc',
]

for t in test_cases:
    print(t, '->', f(t))

ผล:

abc -> cba
tuv? -> v?ut
a(b|c) -> (c|b)a
1[23] -> [23]1
a([bc]|cd) -> (dc|[bc])a
^a[^bc]d$ -> ^d[^bc]a$
x[yz]{1,2} -> [yz]{1,2}x
p{2} -> p{2}
q{7,} -> q{7,}
\[c[de] -> [de]c\[
a{3}b -> ba{3}
(a)?(b)+ -> )+b))?a)                    # <-- note: wrong
[\[]{5}[^\]]{6} -> [^\]]{6}[\[]{5}
[\[]\]{7} -> \]{7}[\[]
[\[\]]{8,9} -> [\[\]]{8,9}
\(\)\^\$ -> \$\^\)\(
ab[c -> c[ba
a(?bc) -> (cb(?a
a[]]bc -> cb[]]a
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.