Untuk tujuan tantangan ini, kami mengatakan bahwa pola regex cocok dengan string jika seluruh string dicocokkan dengan pola, bukan hanya substring.
Mengingat dua pola regex A dan B , kita mengatakan bahwa A adalah lebih khusus dari B jika setiap string yang cocok dengan A juga cocok dengan B tetapi tidak sebaliknya. Kita mengatakan bahwa A adalah setara dengan B jika kedua pola sama persis dengan set yang sama string. Jika pola tidak lebih khusus dari yang lain mereka juga tidak setara, kita mengatakan bahwa A dan B yang tak tertandingi .
Misalnya, polanya Hello, .*!
lebih khusus daripada .*, .*!
; polanya (Hello|Goodbye), World!
dan Hello, World!|Goodbye, World!
setara; dan pola Hello, .*!
dan.*, World!
tidak ada bandingannya.
Relasi "lebih terspesialisasi daripada" mendefinisikan urutan parsial ketat pada set pola regex. Khususnya, untuk semua pola A dan B , tepat satu dari yang berikut ini benar:
- A lebih khusus daripada B ( A < B ).
- B lebih khusus daripada A ( A > B ).
- A dan B adalah setara ( A = B ).
- A dan B tidak tertandingi ( A ∥ B ).
Ketika A dan B tidak dapat dibandingkan, kita dapat membedakan lebih lanjut antara dua kasus:
- A dan B adalah saling lepas ( A ∥ B ), yang berarti bahwa ada string cocok dengan mereka berdua.
- A dan B yang berpotongan ( A ≬ B ), yang berarti bahwa beberapa string dicocokkan oleh keduanya.
Tantangan
Tulis program atau fungsi yang mengambil sepasang pola regex dan membandingkannya menggunakan urutan di atas. Artinya, jika dua pola yang A dan B , program harus menentukan apakah A < B , A > B ,
A = B atau A ∥ B .
× 92% Bonus tambahan diberikan jika, ketika polanya tidak tertandingi, program menentukan apakah mereka berpotongan atau terpisah.
Masukan dan keluaran
Program harus menerima dua pola regex, sebagai string, dalam rasa yang ditentukan di bawah ini. Anda dapat membaca input melalui STDIN , baris perintah , sebagai argumen fungsi atau metode yang setara . Anda dapat mengasumsikan bahwa polanya valid.
Program harus menghasilkan satu dari empat output yang berbeda (atau lima output yang berbeda jika Anda akan mendapatkan bonus di atas,) tergantung pada hasil perbandingan (output yang tepat terserah Anda.) Anda dapat menulis output ke STDOUT , kembalikan sebagai hasil fungsi atau gunakan metode yang setara .
Regex Flavour
Anda dapat mendukung fitur regex apa pun yang Anda suka, tetapi Anda harus mendukung yang berikut:
- Pergantian dengan
|
. - Kuantifikasi dengan
*
. - Pengelompokan dengan
(
dan)
. - Mencocokkan karakter apa pun (mungkin tidak termasuk baris baru) dengan
.
. - (Opsional: × 80% Bonus) Mencocokkan kelas karakter yang sederhana dan yang dinegasikan dengan
[…]
dan[^…]
, masing-masing. Anda tidak harus mendukung kelas karakter yang telah ditentukan sebelumnya (mis.[:digit:]
) Tetapi Anda harus mendukung rentang karakter. - Karakter lolos dengan
\
. Setidaknya harus dimungkinkan untuk meloloskan karakter khusus (yaitu|*().[^-]\
) dan lebih disukai juga karakter khusus yang umum dalam rasa lain (misalnya{}
), tetapi perilaku ketika melarikan diri karakter tidak spesifik tidak ditentukan. Khususnya, Anda tidak harus mendukung urutan pelarian khusus seperti\n
untuk baris baru dan sejenisnya. Sebuah implementasi yang mungkin adalah hanya untuk mengambil karakter mengikuti huruf\
sebagai literal.
Anda dapat mengasumsikan keberadaan karakter input yang tidak dapat dicocokkan dengan literal apa pun (yaitu hanya dapat dicocokkan dengan .
dan kelas karakter yang dinegasikan.)
Aturan tambahan
- Anda dapat menggunakan pustaka regex atau fungsionalitas regex bawaan hanya untuk tujuan pencocokan dan penggantian string.
- Anda dapat mengabaikan masalah terkait lokal, seperti aturan pengumpulan.
- Untuk menyatakan yang sudah jelas: program Anda harus diakhiri. Itu harus dieksekusi dalam jumlah waktu yang wajar diberikan pola-pola khas (pasti tidak lebih dari satu jam, lebih disukai jauh lebih sedikit.)
Mencetak gol
Ini adalah kode-golf. Skor Anda adalah produk dari ukuran kode , dalam byte, dan bonus apa pun . The skor terendah menang.
Uji Kasus
Format kasus uji adalah sebagai berikut:
<Test ID>
<Pattern A>
<Ordering>
<Pattern B>
<Test ID>
<Pattern A>
<Ordering>
<Pattern B>
...
Di mana <Test ID>
pengenal untuk kasus uji, <Pattern A>
dan <Pattern B>
merupakan pola regex dan <Ordering>
urutan di antara mereka, dan merupakan salah satu dari:
<
:<Pattern A>
lebih terspesialisasi daripada<Pattern B>
.>
:<Pattern B>
lebih terspesialisasi daripada<Pattern A>
.=
: Polanya sama.|
: Pola-pola tidak tertandingi dan terpisah.X
: Pola-pola tidak tertandingi dan berpotongan.
Nilai khusus <empty pattern>
berarti pola kosong.
A. Pola dasar
B. Pola kompleks
C. Pola dasar dengan kelas karakter
D. Pola kompleks dengan kelas karakter
Program Tes
Cuplikan berikut dapat digunakan untuk membandingkan pola regex:
<style>#main {display: none;}#main[loaded] {display: inline;}.pattern_container {position: relative;}.pattern_underlay, .pattern {font: 12pt courier, monospace;overflow: hidden;white-space: pre;padding: 7px;box-sizing: border-box;}.pattern_underlay {background-color: #dddddd;color: #707070;border-radius: 4px;box-shadow: 0.5px 0.5px 2.5px #aaaaaa;}.pattern_underlay[error] {background-color: #ffccbb;}.pattern {position: absolute;left: 0px;top: 0px;background: none;border: none;width: 100%;height: 100%;resize: none;white-space: normal;}#ordering {min-width: 28pt;text-align: center;font-size: 16pt;}#status {padding: 5px;background-color: #fffdce;box-shadow: 1.5px 1.5px 3.5px #aaaaaa;font-size: 10pt;white-space: pre;display: none;}#status[error] {display: inline;background-color: #ffe8df;}#status[loading] {display: inline;}.inline_code {background-color: #dddddd;font: 12pt courier, monospace;padding: 2px;}.placeholder {visibility: hidden;}.error_text {background-color: #fffcb7};</style><span id="main"><table><tr><td><div class="pattern_container"><div class="pattern_underlay" id="pattern1_underlay"></div><textarea class="pattern" id="pattern1" oninput="compare()">Hello, .*!</textarea></div></td><td id="ordering"></td><td><div class="pattern_container"><div class="pattern_underlay" id="pattern2_underlay"></div><textarea class="pattern" id="pattern2" oninput="compare()">.*, .*!</textarea></div></td></tr></table><br></span><span id="status" loading>Loading...</span><script type='text/javascript'>var Module = {setStatus: function (status) {document.getElementById("status").innerHTML = status;if (status == "") {compare();document.getElementById("status").removeAttribute("loading");document.getElementById("main").setAttribute("loaded", 1);}}};function underlay_chars(str) {if (/^\n*$/.exec(str))return str.split("\n").map(function () { return '<span class="placeholder"> \n</span>'; });if (str.indexOf("\n") >= 0)str = str.replace(/\s*$/gm, function (m) { return m.replace(/[^\n]/g, "\0"); });return (str + "\n").split("").map(function (c) {if (c == "\0") return "·";else return '<span class="placeholder">' + c + '</span>';});}function underlay_str(str) {return underlay_chars(str).join("");}function str_to_array32(str) {a = [];for (c of str) {n = c.charCodeAt(0);a.push(n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, n >> 24);}a.push(0, 0, 0, 0);return a;}function compare() {try {for (e of ["pattern1_underlay", "pattern2_underlay", "status"])document.getElementById(e).removeAttribute("error");for (e of ["pattern1", "pattern2"])document.getElementById(e + "_underlay").innerHTML = underlay_str(document.getElementById(e).value);c = Module.ccall("regex_compare", "number", ["array", "array"], [str_to_array32(document.getElementById("pattern1").value),str_to_array32(document.getElementById("pattern2").value)]);if (c >= 0)document.getElementById("ordering").innerHTML = "∥≬<>="[c];else {i = Module.ccall("regex_error_index", "number", [], []);l = Module.ccall("regex_error_length", "number", [], []);e = document.getElementById("pattern" + -c + "_underlay");t = underlay_chars(document.getElementById("pattern" + -c).value);e.setAttribute("error", 1);e.innerHTML =t.slice(0, i).join("") +'<span class="error_text">' + t.slice(i, i + l).join("") + "</span>" +t.slice(i + l).join("");e.setAttribute("error", 1);throw "Pattern error: " + Module.ccall("regex_error", "string", [], []).replace(/`(.*?)'/g, '<span class="inline_code">$1</span>');}} catch (e) {document.getElementById("ordering").innerHTML = "??";document.getElementById("status").innerHTML = e;document.getElementById("status").setAttribute("error", 1);}}</script><script async type="text/javascript" src="https://gist.githack.com/anonymous/91f27d6746566c7b4e4c/raw/c563bf84a01c3a1c6e5f021369a3e730a2e74a1a/rpo.js"></script>