Regex Golf: Verifikasi Solusi Sudoku

65

Tulis regex yang cocok dengan solusi sudoku yang valid dan tidak cocok dengan solusi sudoku yang tidak valid. Input adalah versi sudoku yang belum dibuka , artinya tidak ada garis pembatas. Misalnya papan berikut:

7 2 5 8 9 3 4 6 1
8 4 1 6 5 7 3 9 2
3 9 6 1 4 2 7 5 8
4 7 3 5 1 6 8 2 9
1 6 8 4 2 9 5 3 7
9 5 2 3 7 8 1 4 6
2 3 4 7 6 1 9 8 5
6 8 7 9 3 5 2 1 4
5 1 9 2 8 4 6 7 3

akan diberikan sebagai:

725893461841657392396142758473516829168429537952378146234761985687935214519284673

Aturan mungkin sudah menjadi rahasia umum saat ini, tetapi untuk berjaga-jaga ... papan sudoku valid jika dan hanya jika:

  • Setiap baris berisi angka dari 1hingga 9tepat sekali.
  • Setiap kolom berisi angka dari 1hingga 9tepat sekali.
  • Masing-masing dari sembilan subgrids 3x3 berisi angka dari 1ke 9tepat satu kali.

Aturan

Jawaban Anda harus terdiri dari satu regex, tanpa kode tambahan (kecuali, secara opsional, daftar pengubah regex yang diperlukan untuk membuat solusi Anda berfungsi). Anda tidak boleh menggunakan fitur rasa regex bahasa Anda yang memungkinkan Anda untuk memohon kode dalam bahasa hosting (mis. ePengubah Perl ).

Anda dapat menggunakan rasa regex apa pun yang ada sebelum tantangan ini, tetapi harap tentukan rasanya.

Jangan berasumsi bahwa regex berlabuh secara implisit. Misalnya jika Anda menggunakan Python, asumsikan bahwa regex Anda digunakan dengan re.searchdan bukan dengan re.match. Regex Anda tidak perlu cocok dengan seluruh string. Itu hanya perlu mencocokkan setidaknya satu substring (yang mungkin kosong) untuk solusi yang valid dan tidak menghasilkan yang cocok untuk solusi yang tidak valid.

Anda dapat mengasumsikan bahwa input akan selalu berupa 81 digit positif.

Ini adalah golf regex, jadi regex terpendek yang menang. Jika bahasa Anda membutuhkan pembatas (biasanya /.../) untuk menunjukkan ekspresi reguler, jangan hitung pembatas itu sendiri. Jika solusi Anda memerlukan pengubah, tambahkan satu byte per pengubah.

Uji Kasus

Papan yang valid:

123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298
243561789819327456657489132374192865926845317581673294162758943735914628498236571
243156789519847326687392145361475892724918653895263471152684937436729518978531264
498236571735914628162758943581673294926845317374192865657489132819327456243561789
978531264436729518152684937895263471724918653361475892687392145519847326243156789
341572689257698143986413275862341957495726831173985426519234768734869512628157394

Papan tidak valid:

519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825
243561789829317456657489132374192865916845327581673294162758943735924618498236571
243156789529847316687392145361475892714928653895263471152684937436719528978531264
498236571735924618162758943581673294916845327374192865657489132829317456243561789
978531264436719528152684937895263471714928653361475892687392145529847316243156789
342571689257698143986413275861342957495726831173985426519234768734869512628157394
345678192627319458892451673468793521713524986951862347179246835534187269286935714
341572689257698143986413275862341957495726831173985426519234768734869512628517394

Untuk kasus pengujian lebih lanjut, Anda dapat menggunakan skrip CJam ini yang mengambil papan yang valid sebagai input dan secara acak mengocoknya untuk memberikan papan yang valid baru (format input tidak relevan asalkan hanya berisi angka dan opsional spasi).

Jika regex Anda kompatibel dengan rasa .NET, Anda dapat mengujinya secara online menggunakan Retina. Solusi yang valid harus dicetak 0untuk papan yang tidak valid dan beberapa bilangan bulat positif untuk papan yang valid. Untuk menjalankan semua kasus uji sekaligus, gunakan templat ini dan masukkan regex pada baris kedua. Jika Anda memerlukan pengubah regex, tambahkan a `ke regex dan letakkan huruf pengubah standar di depannya.

Martin Ender
sumber
2
terkait codegolf.stackexchange.com/q/22443/15599
Level River St
1
Kalau saja ini [kode-bowling], lol.
mbomb007
Tunggu ... Jika kita menggunakan Python, kita hanya bisa menggunakan ekspresi reguler, dan tidak ada yang lain? Juga, seberapa besar masing-masing papan? Apakah ada ukuran tertentu? Jika tidak, bagaimana kita harus mengekstraksi setiap papan dari rumpun angka di bawah valid boards?
R. Kap
@ R.Kap Terlepas dari rasa apa yang Anda gunakan, Anda harus mengirimkan hanya regex (dan mungkin beberapa pengubah), ya. Setiap input persis 81 digit dan mewakili papan penuh. (Setiap baris dalam kasus uji adalah papan terpisah.)
Martin Ender
Saya menulis sebuah skrip untuk memecahkan sudoku sederhana dalam SQL. Saya yakin ini dapat ditulis ulang untuk pertanyaan ini. Namun SQL tidak memiliki banyak REGEX. Apakah itu mendiskualifikasi jawabannya? (Script mungkin akan sedikit di bawah 400 karakter)
t-clausen.dk

Jawaban:

40

Ruby regex, 71 78 73 byte

^(?!.*(?=(.))(.{9}+|(.(?!.{9}*$))+|(?>.(?!.{3}*$)|(.(?!.{27}*$)){7})+)\1)

Saya tidak benar-benar tahu Ruby, tetapi ternyata tidak mengeluh tentang penjumlahan berjenjang.

Coba di sini.

.NET regex, 79 78 75 atau 77 byte

Karena Martin berpikir ini mungkin ... Tapi kurasa dia hanya akan memasukkan perubahan ini juga.

^(?!(.)+((.{9})+|(?>(.{9})+
|.)+|(?((...)*
)(?>(.{27})+
|.){7}|.)+)(?<=\1))

Membutuhkan baris tambahan di input untuk bekerja. Saya tidak yakin apakah saya diizinkan melakukan ini (mungkin tidak).

Coba di sini.

Versi waras 77 byte:

^(?!(.)+((.{9})+|((?!(.{9})*$).)+|(?((...)*$)((?!(.{27})*$).){7}|.)+)(?<=\1))

Terima kasih Neil untuk menunjukkan kesalahan pada versi saya sebelumnya dan bermain golf 1 byte (untuk (...)*).

Coba di sini.

PCRE, 77 78 byte

^(?!.*(?=(.))((.{9})+|(.(?!(?3)*$))+|(?(?=.(...)*$)(.(?!(.{27})*$)){7}|.)+)\1)

Hanya untuk kelengkapan.

Coba di sini.

Versi lain, juga 78 byte:

^(?!.*(?=(.))((.{9})+|(.(?!(?3)*$))+|(?>.(?!(...)*$)|(.(?!(.{27})*$)){7})+)\1)

Coba di sini.

Penjelasan

^(?!.*                    # Match a string that doesn't contain the pattern,
                          # at any position.
  (?=(.))                 # Capture the next character.
  (
    (.{9})+               # Any 9*n characters. The next character is in
                          # the same column as the captured one.
  |
    (.(?!(.{9})*$))+      # Any n characters not followed by a positions 9*m
                          # to the end. The next character is in the same row
                          # as the captured one.
  |
    (                     # Any n occasions of...
    ?(.(...)*$)           # If it is at a position 3*k+1 to the end:
      (.(?!(.{27})*$)){7} # Then count 7*m characters that are not followed
                          # by a position 27*j to the end,
    |
      .                   # Else count any character.
    )+                    # The next character is in the same block as the
                          # captured one.
  )
  \1                      # Fail if the next character is the captured character.
)
jimmy23013
sumber
Wow pekerjaan bagus. Saya hanya mendapatkannya di 83 di. NET dan harus beralih ke PCRE untuk 78. Saya tidak ragu Anda akhirnya akan mengalahkan itu juga. :)
Martin Ender
@ MartinBüttner Yap.
Nic Hartley
Saya pikir saya menggunakan lookahead untuk mengalahkan @ MartinBüttner dengan (pada saat itu) 4 byte rapi tetapi Anda telah mengambil itu ke tingkat berikutnya.
Neil
Maaf, tetapi ini tidak mendeteksi apakah sel-sel di (1, 2) dan (2, 1) adalah sama, dan juga untuk semua sel lain dalam kotak di mana duplikat di bawah dan di sebelah kiri.
Neil
1
@ MartinBüttner Saya baru menyadari bahwa saya dapat menerjemahkan versi PCRE kedua saya ke Ruby ... Saya kira Anda dapat memposting jawaban Anda sekarang ...
jimmy23013
34

PCRE, 117 119 130 133 147 byte

^(?!(.{27})*(...){0,2}(.{9})?.?.?(.).?.?(?=(?2)*$).{6,8}(?3)?\4.{0,17}(?1)*$|.*(.)(.{8}(?3)*|((?!(?3)*$)(|.(?7))))\5)

Harus juga bekerja dengan rasa Python, Java, dll. Sekarang dengan rekursi! Dan fitur "rekursi" menggunakan non-rekursif untuk "subrutin", yang saya benar-benar lupa sampai saya harus menggunakan rekursi yang sebenarnya.

feersum
sumber
Ide keren - hindari pengulangan alih-alih mencocokkan norepeats!
Qwertiy
1
Sayang sekali Anda tidak bisa menulis .{27}*.
Neil
Bah, saya akan memutarkan solusi 133 byte Anda menjadi 121 byte hanya untuk menemukan bahwa Anda telah menulis ulang, tetapi ini dia:^(?!(.{27})*(.{9})?(...){0,2}.?.?(.).?.?(?=(...)*$)(.{9})?.{6,8}\4.{0,17}(.{27})*$|.*(.)((.{9})+|((?!(.{9})*$).)+)(<=\8))
Neil
@Nil Apa rasa itu? PCRE atau orang lain yang saya tahu tidak mengizinkan referensi di belakang terlihat.
feersum
@ Neil (<=\8)tidak terlihat seperti sintaks yang valid (tidak ada a ?). Juga, satu-satunya rasa yang saya tahu yang mendukung referensi di lookbehinds adalah .NET.
Martin Ender
15

.NET regex, 8339 byte

Ya, saya tahu solusi saya sangat naif, karena Martin mengatakan dia melakukannya dalam 130 byte. Faktanya, URL untuk mencobanya online sangat panjang sehingga saya tidak dapat menemukan pemendek URL yang akan menerimanya.

(code removed, since it's so long nobody will read it here, 
and it made the post take forever to load. Just use the "Try it online" link.)

Tautan di bawah ini tidak berfungsi di IE, tetapi bekerja di Chrome dan Firefox.

Cobalah online - Semua uji sekaligus, dengan bantuan!`di awal, tidak termasuk dalam hitungan byte.


Inilah skrip Python yang saya gunakan untuk membuatnya (kode di bawah):

R=range(0,9)
S=range(1,10)

o = ""

# validate rows
T = "(?=.{%s,%s}%s)"
for j in R:
    for i in S:
        o += T % (9*j,9*(j+1)-1, i)

# validate columns
# "(?=(.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s}|.{%s})%s)"
T = "(?=("+"|".join([".{%s}"]*9)+")%s)"
for j in R:
    for i in S:
        o += T % (j,j+9,j+18,j+27,j+36,j+45,j+54,j+63,j+72, i)

# validate boxes
# (?=.{0,2}1|.{9,11}1|.{18,20}1)(?=.{3,5}1|.{12,14}1|.{21,23}1)
# (?=.{27,29}1|.{36,38}1|.{45,47}1)
T = ".{%s,%s}%s"
for i in S:
    for x in (0,27,54):
        for y in (0,3,6):
            o += "(?="+"|".join(T % (x+y+z,x+y+z+2, i) for z in (0,9,18))+")"

o += ".{81}"

o = o.replace(".{0}","").replace(",80}",",}")
print(o)
mbomb007
sumber
1
Saya mendukung Anda
Martijn
4
Tahu apa yang lucu? Tautan online try it akan membuat IE macet karena terlalu panjang: P
cat
15
@ kucing Itulah sebabnya satu-satunya tujuan nyata IE adalah memungkinkan pengguna mengunduh Firefox (atau Chromium).
Byte Commander
2
@ kucing Ini tidak crash IE11 pada Windows 8.1, meskipun Regex tidak diproses dengan benar.
Nzall
2
@ kucing Itu tidak crash IE 11 saya di Windows 7. Itu hanya memotong URL.
mbomb007
14

.NET regex, 121 byte

^(?!(.{27})*(.{9})?(...){0,2}.?.?(.).?.?(?=(...)*$)(.{9})?.{6,8}\4.{0,17}(.{27})*$|.*(?=(.))((.{9})+|(.(?!(.{9})*$))+)\8)

Penjelasan:

^(?!                     Invert match (because we're excluding duplicates)
 (.{27})*                Skip 0, 3 or 6 rows
 (.{9})?                 Optionally skip another row
 (...){0,2}              Skip 0, 3 or 6 columns
 .?.?(.).?.?(?=(...)*$)  Choose any of the next three cells
 (.{9})?                 Optionally skip another row
 .{6,8}\4                Match any of the three cells below
 .{0,17}(.{27})*$        As long as they're from the same square
|                        OR
 .*(?=(.))(              Choose any cell
  (.{9})+                Skip at least one row
 |                       or
  (.                     Skip cells
   (?!(.{9})*$)          Without reaching the end of the row
  )+                     For at least one cell (i.e. the cell chosen above)
 )\8)                    Match the chosen cell to the next cell
)
Neil
sumber
Bagus, kombinasi baris dan kolom Anda cukup pintar. Itu menghemat 4 byte pada solusi saya sendiri. :)
Martin Ender
8

PCRE, 3579 byte

Solusi brute force yang benar-benar mengerikan. Tampilan negatif di belakang ahoy!

Saya menghabiskan terlalu banyak waktu untuk mengabaikannya, jadi ini dia, demi anak cucu.

Sisi baiknya, jika Sudoku tiba-tiba mulai menggunakan 9 karakter yang berbeda, ini masih akan berfungsi, saya kira ...

http://pastebin.com/raw/CwtviGkC

Saya tidak tahu cara mengoperasikan Retina, tetapi Anda juga dapat menempelkannya ke https://regex101.com atau serupa dan itu akan cocok.

Kode Ruby yang digunakan untuk menghasilkan regex:

# Calculate the block you're in
def block(x)
    x /= 3
    x + x%3 - x%9
end

81.times do |i|
    row, col = i.divmod(9)
    neg = []
    neg += (0...col).map {|e| 9*row + e + 1}
    neg += (0...row).map {|e| 9*e + col + 1}
    neg += (0...i).map {|e| e + 1 if block(e) == block(i)}.compact
    neg = neg.uniq.sort.map {|e| "\\#{e}"}
    if neg.size > 0
        print "(?!#{neg.join '|'})"
    end
    print "(.)"
end
Nilai Tinta
sumber
8

Rasa Ruby, 75 74 byte

Terima kasih kepada jimmy23013 untuk menghemat 1 byte.

^(?!(.{9}*(.|(.)){,8}|.*(\g<2>.{8})*|.{27}?.{3}?(\g<2>{3}.{6}){,2}.?.?)\3).

Uji di sini.

Sekarang setelah dipukuli, saya bisa membagikan solusi saya sendiri. :) Saya menemukan teknik regex yang menarik (mungkin baru?) Dalam proses ( (.|(.)){,8}\3bagian), yang mungkin tidak terkalahkan dalam kasus-kasus di mana ini tidak dapat dikombinasikan dengan bagian lain dari regex (seperti halnya dalam jawaban jimmy23013) .

Penjelasan

Seperti jawaban singkat lainnya, saya menggunakan lookahead negatif yang mencari duplikat dalam baris, kolom, atau blok. Blok bangunan dasar dari solusinya adalah ini:

(.|(.))...\3

Perhatikan bahwa \3digunakan kembali di antara tiga alternatif berbeda (yang semuanya menggunakan grup 3untuk deteksi duplikat).

Grup di sebelah kiri (yang merupakan grup 2, yang berisi grup 3) digunakan untuk posisi apa pun yang dapat berisi bagian pertama dari digit duplikat (dalam grup yang tidak boleh berisi digit duplikat). Kemudian ...adalah sesuatu yang membuat kita posisi berikutnya di mana angka seperti itu mungkin terjadi (jika perlu) dan \3mencoba untuk menemukan paruh kedua dari duplikat melalui backreference. Alasan ini berhasil mundur. Ketika mesin pertama kali cocok (.|(.))itu hanya akan digunakan .setiap waktu dan tidak menangkap apa pun. Sekarang \3pada akhirnya gagal. Tapi sekarang mesin secara bertahap akan mencoba menggunakan (.)bukan .untuk pertandingan individu Pada akhirnya, jika ada duplikat, itu akan menemukan kombinasi mana(.)terakhir digunakan pada digit pertama duplikat (sedemikian rupa sehingga tangkapan tidak ditimpa nanti), dan kemudian menggunakan beberapa lainnya .untuk menjembatani celah ke referensi-ulang. Jika ada duplikat, mundur akan selalu menemukannya.

Mari kita lihat tiga bagian berbeda tempat ini digunakan:

.{9}*(.|(.)){,8}

Ini memeriksa duplikat di beberapa baris. Pertama kita lewati ke baris mana saja dengan .{9}*. Kemudian kami mencocokkan hingga 8 karakter (yaitu apa pun di baris itu kecuali digit terakhir) menggunakan tangkapan duplikat opsional dan mencoba menemukan \3setelahnya.

.*(\g<2>.{8})*

Ini mencari duplikat di beberapa kolom. Pertama, perhatikan bahwa itu \g<2>adalah panggilan subrutin, jadi ini sama dengan:

.*((.|(.)).{8})*

di mana dua grup yang baru saja kami masukkan masih disebut sebagai 2dan 3.

Di sini, .*cukup melompati sejauh yang diperlukan (itu akan cukup untuk mencocokkan hingga 8 karakter di sini, tetapi biaya lebih banyak byte). Kemudian kelompok luar mencocokkan satu baris lengkap (yang dapat membungkus dua baris fisik) sekaligus, secara opsional menangkap karakter pertama. Ini \3akan dicari tepat setelah ini, yang memastikan penyelarasan vertikal antara tangkapan dan backreference.

Akhirnya, periksa blok:

.{27}?.{3}?(\g<2>{3}.{6}){,2}.?.?

Sekali lagi, \g<2>ini adalah panggilan subrutin, jadi ini sama dengan:

.{27}?.{3}?((.|(.)){3}.{6}){,2}.?.?

Untuk memverifikasi blok, perhatikan bahwa karena kami telah memeriksa semua baris dan kolom, kami hanya perlu memeriksa empat dari blok 3x3. Ketika kami tahu bahwa semua baris dan kolom serta blok 3x3 ini benar:

XX.
XX.
...

Lalu kita tahu bahwa tidak mungkin ada duplikat di blok yang tersisa. Karenanya saya hanya memeriksa empat blok ini. Selain itu, perhatikan bahwa kami tidak harus mencari duplikat dalam baris yang sama dari blok 3x3. Cukup menemukan paruh pertama duplikat dalam satu baris dan mencari paruh kedua berturut-turut di bawah.

Sekarang untuk kode itu sendiri, pertama-tama kita lompat ke awal salah satu dari empat blok dengan .{27}?.{3}?(opsional lewati tiga baris, opsional lewati tiga kolom). Kemudian kami mencoba mencocokkan dua baris dari blok 3x3 dengan trik yang sama dengan yang kami gunakan untuk baris sebelumnya:

(.|(.)){3}.{6}

Kami mengizinkan tetapi tidak perlu menangkap salah satu dari 3 sel di baris saat ini dari blok 3x3 dan kemudian melompat ke baris berikutnya dengan .{6}. Terakhir, kami mencoba menemukan duplikat di salah satu dari 3 sel dari baris yang kami tuju:

.?.?

Dan itu saja.

Martin Ender
sumber
74 ^(?!(.*((.|(.)).{8})*|.{9}*\g<3>{,8}|.{27}?.{3}?(\g<3>{3}.{6}){,2}.?.?)\4):; 73: ^(?!(.*((.|(.)|\4()).{8})*|.{9}*\g<3>{9}|.{27}?.{3}?(\g<3>{3}.{6}){3})\5).
jimmy23013
@ jimmy23013 Saya sebenarnya menggunakan \4()trik dalam versi sebelumnya untuk blok 3x3, tetapi akhirnya menyingkirkannya, karena itu lebih lama. : D
Martin Ender
@ jimmy23013 73 salah satu tidak memeriksa baris terakhir meskipun:341572689257698143986413275862341957495726831173985426519234768734869512628517394
Martin Ender
6

Javascript regex, 532 530 481 463 karakter

Validasi baris:

/^((?=.{0,8}1)(?=.{0,8}2)(?=.{0,8}3)(?=.{0,8}4)(?=.{0,8}5)(?=.{0,8}6)(?=.{0,8}7)(?=.{0,8}8)(?=.{0,8}9).{9})+$/

Validasi kolom:

/^((?=(.{9}){0,8}1)(?=(.{9}){0,8}2)(?=(.{9}){0,8}3)(?=(.{9}){0,8}4)(?=(.{9}){0,8}5)(?=(.{9}){0,8}6)(?=(.{9}){0,8}7)(?=(.{9}){0,8}8)(?=(.{9}){0,8}9).){9}/

Validasikan kuadrat dari karakter pertama:

/(?=.?.?(.{9}){0,2}1)(?=.?.?(.{9}){0,2}2)(?=.?.?(.{9}){0,2}3)(?=.?.?(.{9}){0,2}4)(?=.?.?(.{9}){0,2}5)(?=.?.?(.{9}){0,2}6)(?=.?.?(.{9}){0,2}7)(?=.?.?(.{9}){0,2}8)(?=.?.?(.{9}){0,2}9)/

Setel pratinjau untuk memulai alun-alun:

/^(((?=)...){3}.{18})+$/

Dan seluruh ekspresi:

/^(?=((?=.{0,8}1)(?=.{0,8}2)(?=.{0,8}3)(?=.{0,8}4)(?=.{0,8}5)(?=.{0,8}6)(?=.{0,8}7)(?=.{0,8}8)(?=.{0,8}9).{9})+$)(?=((?=(.{9}){0,8}1)(?=(.{9}){0,8}2)(?=(.{9}){0,8}3)(?=(.{9}){0,8}4)(?=(.{9}){0,8}5)(?=(.{9}){0,8}6)(?=(.{9}){0,8}7)(?=(.{9}){0,8}8)(?=(.{9}){0,8}9).){9})(((?=.?.?(.{9}){0,2}1)(?=.?.?(.{9}){0,2}2)(?=.?.?(.{9}){0,2}3)(?=.?.?(.{9}){0,2}4)(?=.?.?(.{9}){0,2}5)(?=.?.?(.{9}){0,2}6)(?=.?.?(.{9}){0,2}7)(?=.?.?(.{9}){0,2}8)(?=.?.?(.{9}){0,2}9)...){3}.{18})+$/

Cocok dengan seluruh string.


Uji dalam Javascript ES6:

r = /^(?=((?=.{0,8}1)(?=.{0,8}2)(?=.{0,8}3)(?=.{0,8}4)(?=.{0,8}5)(?=.{0,8}6)(?=.{0,8}7)(?=.{0,8}8)(?=.{0,8}9).{9})+$)(?=((?=(.{9}){0,8}1)(?=(.{9}){0,8}2)(?=(.{9}){0,8}3)(?=(.{9}){0,8}4)(?=(.{9}){0,8}5)(?=(.{9}){0,8}6)(?=(.{9}){0,8}7)(?=(.{9}){0,8}8)(?=(.{9}){0,8}9).){9})(((?=.?.?(.{9}){0,2}1)(?=.?.?(.{9}){0,2}2)(?=.?.?(.{9}){0,2}3)(?=.?.?(.{9}){0,2}4)(?=.?.?(.{9}){0,2}5)(?=.?.?(.{9}){0,2}6)(?=.?.?(.{9}){0,2}7)(?=.?.?(.{9}){0,2}8)(?=.?.?(.{9}){0,2}9)...){3}.{18})+$/
;`123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298`
.split`
`.every(r.test.bind(r))
&&
`519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825`
.split`
`.every(s => !r.test(s))
Qwertiy
sumber
Saya pikir kolom harus jauh lebih mudah daripada baris, jadi saya merasa aneh bahwa regex kolom Anda lebih panjang daripada baris Anda.
Peter Taylor
@ PeterTaylor, mereka memiliki struktur yang sama, tetapi untuk kolom saya harus melewati 9 karakter bukan 1, jadi .masuk ke dalam (.{9})kurung karena yang berikutnya {0,8}. Menurut Anda mengapa kolom harus lebih pendek?
Qwertiy
@ PeterTaylor, ya, kolom akan lebih sederhana jika saya kira untuk memeriksa negasi.
Qwertiy
@ SuperJedi224, mengapa javascript? Saya berharap regex ini berlaku di mana-mana.
Qwertiy
6
@Qwertiy Meskipun regex Anda harus bekerja dalam banyak rasa, ia bergantung pada lookaheads (tidak tersedia di Lua atau OCaml, misalnya). Ini juga merupakan ekspresi reguler dasar atau diperluas yang tidak valid, yang menggunakan sintaks yang sama sekali berbeda. Yang terbaik adalah memilih rasa untuk klaim validitas, bahkan jika solusinya bekerja di banyak orang lain.
Dennis