Düzenli İfadeleri Derleme (İkame İle)


21

Göreviniz regex'te derlemek ... ... regex'deki her karakterin yerine geçecek şekilde belirleyerek.

regexes

Regex'ler bunları destekliyor

REGEX       = (LITERAL REGEX / GROUP REGEX / STAR REGEX / ALTERNATIVE)
LITERAL     = 1 / 0
GROUP       = '(' REGEX ')'
STAR        = (LITERAL / GROUP) '*'
ALTERNATIVE = '('REGEX ('|' REGEX)*')'

Neden sadece 1 veya 0? Basitleştirme içindir. Bu nedenle regex yalnızca aşağıdaki karakterlere sahiptir:

*()|10

Aşağıdaki gibi yorumlanır:

  1. * Kleene yıldızı (sol grubu veya değişmez 0 veya daha fazla kez tekrarlayın).
  2. | alternatiftir (sola gelen regex veya sağa regex eşleşirse eşleşir).
  3. () gruplandırıyor.
  4. 1 karakter 1 ile eşleşir.
  5. 0 0 karakteriyle eşleşir.

Nasıl derlenir?

Altı kod parçacığını belirtirsiniz: her bir regex karakterini değiştirmek için bir tane. Örneğin, cevabınız:

*: FSAGFSDVADFS
|: GSDGSAG
(: GSDG
): GDSIH
1: RGIHAIGH
0:GIHEBN

Ardından her bir regex'i kod snippet'iyle değiştirin, yani:

(0|11)*

çevrildi:

GSDGGIHEBNGSDGSAGRGIHAIGHRGIHAIGHGDSIHFSAGFSDVADFS

Yapılması gereken program ne yapmalı?

Programınız:

  1. Girişi alın.
  2. Eğer regex bütün girdiyle eşleşiyorsa, gerçek bir değer çıktılar.
  3. Başka çıktı, sahte bir değer.

Dış giriş 01, tanımsız davranış olarak kabul edilir. Giriş boş olabilir.

Ek kurallar

  1. Belirli bir regex karakteri için, ortaya çıkan snippet'in her zaman aynı olması gerekir.
  2. Daha sonra eklenen hiçbir önek veya sonek karakteri yoktur.
  3. Regex'in boş olmadığı garantilidir.

puanlama

En düşük kombine snippet kazanır. Dolayısıyla örnek olay için puan şu şekilde hesaplanır:

FSAGFSDVADFS+ GSDGSAG+ GSDG+ GDSIH+ RGIHAIGH+GIHEBN

12 + 7 + 4 + 5 + 8 + 6 = 42


Her snippet en az 1 karakter uzunluğunda mı?
trichoplax

Snippet'in uzunluğu sıfır olabilir. Düzenleme tamam.
Akangka

RegEx dili bu zorluk için geçerli mi? : P
Loovjo

RegEx'in Regre'ye sahip olduğunu düşünüyorum. Bunu yapmak zorundayım. Retina ve regex'i dışlamak istiyorum, ancak Mego'ya göre izin verilmiyor. Yine de, Salyangozlar ve arkadaşlar hakkında hiçbir şey bilmiyorum.
Akangka

@HristiyanIrwan İlginç bir şekilde, bunun hala Retina'da çözülebileceğinden emin değilim ve öyle olsa bile, rekabetten uzak olacağına eminim.
Martin Ender

Yanıtlar:


7

Salyangoz , 48 bayt

0 -> )0(\0!(l.)(~

1 -> )0(\1!(l.)(~

( -> )0({{(

) -> )0}}(~

| -> )0}|{(

* -> )0),(~

Yalnızca tam girişi eşleştirmek yerine kısmi eşleşmeleri aramak zorunda olsaydık çok kolay olurdu. 0olur \0, 1olur \1, *olur ,ve diğerleri kendilerine eşlenirdi. Bunun yerine kibritlerin başlangıçtan başka bir yerden başlamasını ya da sondan başka bir yerden bitmesini önlemek için pek çok şenan insan vardır. !(l.)eğer eşleşmenin başlangıcı girişin başında değilse, başarısız olacak bir iddia. ~girişin dışındaki bir hücreyle eşleştiği için, regex'in sonunda olmasına izin verilen tüm karakterlere eklenir. Aşağıdaki başka bir regex karakteri varsa, sayısal bir niceleyici tarafından iptal edilir0Bu, 0 kez eşleştirilmesini gerektirir, aslında yorum yapar. İzin vermek için *( ,), dilin braket eşleme kuralları yoğun olarak kullanılan out-of-sınırları şekilde varlık testi mankeni rağmen düzgün çalışması için. Belgelerden:

Eşleşen parantez çiftleri ()veya küme parantezleri {}beklendiği gibi davranır (regex'teki parantezler gibi), ancak aşağıdaki kurallara göre bir çiftin yarısını dışarıda bırakmak ve bunun çıkarımını yapmak da mümkündür. )veya }aynı tipteki ( (veya {sırasıyla) en yakın kapatılmamış grup açılış talimatına veya mevcut değilse, modelin başına kadar her şeyi sola gruplar . Bu aralığın ortasında zıt tipteki kapatılmamış açma talimatlarını kapatır. Aksi takdirde eşleşmeyen (veya {kalıbın sonuna kadar kapanır.

Çamur gibi temizle değil mi?


İç çek, regex'in dışında eşleşen bir dilin bile olduğunu unuttum. Güzel iş, ama özür dilerim, oy yok (oy yok, oy yok)
Akangka

@HristiyanIrwan, bu sitede, çoğu 1d dejenere kullanımına sahip 2d eşleştirme dilleri geliştirmek için tam bir zorluk var. codegolf.stackexchange.com/questions/47311/…
Sparr

7

CJam, 151 bayt

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

Satırlar karakterlere karşılık gelir 01(|)*(bu sırayla). Çevrimiçi deneyin!

Bu, hiçbir yerleşik normal ifade veya diğer desen eşleştirme türlerini kullanmaz. Aslında, CJam bu özelliklerin hiçbirine sahip değil. Bunun yerine, temsil ve olası tüm dizeleri oluşturur düzenli ifade başlar olabilir kullanıcı girişi bunlardan biri olup olmadığını nihayet kontrol etmek, maç.

Test çalıştırması

Aşağıdaki, STDIN'den düzenli bir ifade okuyan, karakterlerinin her birini uygun snippet ile değiştiren bir program kullanır ve son olarak oluşturulan kodu komut satırı argümanında belirtilen girdiyle eşleşip eşleşmediğini görmek için değerlendirir.

$ cat regex.cjam
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

"N%ers~
$ cjam regex.cjam '' <<< '(|)'
1
$ cjam regex.cjam '0' <<< '(|)'
0
$ cjam regex.cjam '' <<< '0(|)'
0
$ cjam regex.cjam '0' <<< '0(|)'
1
$ cjam regex.cjam '' <<< '(0|11)*'
1
$ cjam regex.cjam '0' <<< '(0|11)*'
1
$ cjam regex.cjam '11' <<< '(0|11)*'
1
$ cjam regex.cjam '011011000' <<< '(0|11)*'
1
$ cjam regex.cjam '1010' <<< '(0|11)*'
0

Ne yazık ki, bu özellikle hızlı değil. Girişte 9'dan fazla karakter veya regex'te tek bir Kleene yıldızı varsa, oldukça hızlı bir şekilde boğulacaktır.

5 ekstra bayt pahasına - toplam 156 bayt için - potansiyel girdiyle eşleşmek ve bunları tekilleştirmek için daha kısa stringler üretebiliriz. Bu, kodun çalışma şeklini değiştirmez; sadece daha verimli hale getirir.

$ cat regex-fast.cjam 
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+eas,)m*:sSf-L|\"T

"N%ers~
$ cjam regex-fast.cjam '0101001010' <<< '(01|10)*'
0
$ cjam regex-fast.cjam '011001101001' <<< '(01|10)*'
1
$ cjam regex-fast.cjam '0' <<< '(0*1)*'
0
$ time cjam regex-fast.cjam '101001' <<< '(0*1)*'
1

Bunu nasıl daha kısa ve / veya daha hızlı hale getirebileceğime dair hala bir fikrim var. Sonuçlardan memnun kaldığımda bir açıklama ekleyeceğim.
Dennis

Gereksiz gibi görünüyor `-escaping of the için desende `" *. Ne olursa olsun bunun, ben bile regex sadece oluşur en basit durum için, bu program da giriş kabul etmek alamadım 0(testi bakınız çevrimiçi tercüman ). Am Yanlış yapıyorum?
mat

1
@ matz Kodum, bu tercümanda uygulanmayan komut satırı argümanlarını kullanır. Bunun yerine bunu deneyin .
Dennis
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.