Bir regex ters


27

Meydan okuma

Geçerli bir regex verildiğinde, aynı dizelerle eşleşen ancak tersine çevrilen bir regex verin.

Görev

Bu zorluk en temel regex işlemlerini kullanır: ^, $, ?, +, *, [], {}, |. Yakalama grupları ya da o karmaşık şeylerden hiçbiri gibi bir şey yoktur. Özel karakterler kaçabilir.

Örnek Giriş / Çıkış

Not: Geçersiz giriş asla verilmez ve verilen bir giriş için genellikle birden fazla olası cevap vardır!

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>

gösteri

Doğru giriş / çıkışları gösteren çalışma demosu . Bunun, gerçek bir cevapta gerekli olmayan girişleri doğrulamak için ek bir mantığı vardır. Tanımlanmamış davranış olarak geçersiz girdiler düşünün.

Ayrıntılı Bilgiler

Basit olması için, tüm özel karakterlerin ya özel anlamları vardır ya da kaçılırlar; yani, [[]bir karakter aralığı değil [. Uzunluk aralıkları standart POSIX ERE'lerden gelir; olduğunu, {n}, {n,}ve {n,m}desteklenmektedir. Karakter değişiyor []ve [^]destekleniyor. Bu kurallar nedeniyle ve geçersiz bir giriş olmadığından, yalnızca bunların içeriğini doğrudan çıktıya kopyalamanız gerekir. Son olarak, açgözlülük önemli değil, yani tersine çevrilen regex'in önce farklı bir eşleşme bulması önemli değil , sadece aynı dizgiler için bir eşleşme bulması gerekiyor.

puanlama

Bayt cinsinden en küçük program (ağ istekleri gibi hile engelleme) kazanır. Program ya gerçek IO kullanabilir ya da sadece bir fonksiyon tanımlayabilir.


1
Çünkü ?bağlanacak bir şey yok . /a(?bc)/Tarayıcının konsoluna yazmaya çalışın .
TND

3
Şimdi iyi görünüyor (^a|b)(c$|d)Yine de bir test durumu gibi bir şey eklemek isteyebilirsiniz .
Martin Ender

Girişin yalnızca yazdırılabilir ASCII karakterleri içereceğini varsayabilir miyiz? Özellikle, satır karakterleri yok mu?
Martin Ender,

1
Gruplara uygulanan eleme yani düşünmelisiniz (a)?(b)+(b)+(a)??
kennytm

1
()Örnekte kullanılan regex işlem listeniz eksik .
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Yanıtlar:


7

Retina , 136 114 110 bayt

Hey dostum, regex'i sevdiğini duydum ...

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

Burada <empty>, boş bir arka çizgisini temsil eder. Kodu tek bir dosyadan -sbayrakla çalıştırın.

... regex'i ters çevirmek istediğinizde regex kullanmalısınız. Regex kullanmak istediğinizde regex tabanlı bir programlama dili kullanmalısınız.

Bu kod, girişin ne boşluk ;ne !de boşluk içerdiğini varsayar . Oldukça güçlü ve potansiyel olarak geçersiz bir varsayım <DEL>olduğunu kabul etmeme rağmen , koddaki bu üç kodu yazdırılamayan üç karakterle (boş baytlar, zil karakterleri, adlandırdığınız gibi) değiştirebilir ve kod boyutunu veya işlevselliğini etkilemez hiç.

Golf bittiğinde bir açıklama ekleyeceğim.


3
"Ben
sürtüm

Kodun, regex'in herhangi bir ham yeni satır karakteri içermediğini de varsaydığını düşünüyorum.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Oh, bu doğru, girdide yazdırılamayan karakter olmayacağı varsayımı altındaydım. OP’den açıklama aldığımızda bunu düzelteceğim. (Herhangi bir karakter görünebilirse, bu zorluğun geçerli bir regex olarak gördüğü şeyi göstermeyen bazı kombinasyonlar vardır, örneğin ]]], bu nedenle, bu yanıtın çok fazla değişikliğe ihtiyacı yoktur.)
Martin Ender

bir yıl sonra golf yaptım? : P
Okx

2

JavaScript ES6, 574 bayt

Muhtemelen birkaç varifadeyi kaldırabilirim .

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, denenmemiş, 559 bayt

Evde test edecek.

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, ungolfed, 961 bayt

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
lol,
regex'i

3
@ ΚριτικσιΛίθος Evet, yaptım: D Yapabilseydim HTML'yi ayrıştırmak için kullanırdım ...
Conor O'Brien

4
"eğer yapabilirsen"
Doktor

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ i çözümlü regex ile kodlar ancak unicode karakter ile ciddi bir sorun var html
Abr001am

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Bu bir alternatiftir: `code.replace (/.*/," trollolol ");
Kritixi Lithos

2

JavaScript ES6, 343 bayt

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]

Orijinal kod (işlevler, ancak işlevler hariç 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]

Kod, özyinelemeli yukarıdan aşağıya bir çözümleyici olarak uygulanır; bu nedenle, derinlemesine yuvalanmış girdilerde yığının taşmasına neden olabilir.

Kod, geçersiz durumlarda sonsuz döngüye neden olabilir, çünkü "tanımsız davranış" deyiminden yararlanarak bunları sınamadım.


0

Python 3, 144 bayt

(Bu, bir grup üzerinde elemeleri desteklemez gibi (a)+(b)*(cde)?.)

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

Test durumları:

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))

Sonuç:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.