Regex Golf: Überprüfen Sie eine Sudoku-Lösung


65

Schreiben Sie einen regulären Ausdruck, der einer gültigen Sudoku- Lösung und keiner ungültigen Sudoku-Lösung entspricht. Die Eingabe ist eine nicht gerollte Version des Sudoku, dh es gibt keine Zeilenbegrenzer. ZB die folgende Tafel:

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

würde gegeben sein als:

725893461841657392396142758473516829168429537952378146234761985687935214519284673

Die Regeln sind wahrscheinlich mittlerweile allgemein bekannt, aber nur für den Fall ... ein Sudoku-Board ist nur dann gültig, wenn:

  • Jede Zeile enthält die Ziffern von 1bis 9genau einmal.
  • Jede Spalte enthält die Ziffern von 1bis 9genau einmal.
  • Jedes der neun 3x3-Subgrids enthält die Ziffern von 1bis 9genau einmal.

Regeln

Ihre Antwort sollte aus einem einzelnen regulären Ausdruck ohne zusätzlichen Code bestehen (außer optional einer Liste von regulären Ausdrucksmodifikatoren, die erforderlich sind, damit Ihre Lösung funktioniert). Sie dürfen keine Funktionen der Regex-Variante Ihrer Sprache verwenden, mit denen Sie Code in der Hosting-Sprache aufrufen können (z. B. der Perl- eModifikator).

Sie können jedes Regex-Aroma verwenden, das vor dieser Herausforderung existierte, aber geben Sie das Aroma an.

Nehmen Sie nicht an, dass der reguläre Ausdruck implizit verankert ist. Wenn Sie beispielsweise Python verwenden, gehen Sie davon aus, dass Ihre Regex mit re.searchund nicht mit verwendet wird re.match. Ihr regulärer Ausdruck muss nicht mit der gesamten Zeichenfolge übereinstimmen. Es muss nur mindestens eine Unterzeichenfolge (die leer sein kann) für gültige Lösungen entsprechen und keine Übereinstimmungen für ungültige Lösungen ergeben.

Sie können davon ausgehen, dass die Eingabe immer eine Zeichenfolge mit 81 positiven Stellen ist.

Dies ist Regex-Golf, also gewinnt der kürzeste Regex in Bytes. Wenn in Ihrer Sprache (normalerweise /.../) Begrenzer für reguläre Ausdrücke erforderlich sind, zählen Sie die Begrenzer nicht selbst. Wenn Ihre Lösung Modifikatoren erfordert, fügen Sie ein Byte pro Modifikator hinzu.

Testfälle

Gültige Tafeln:

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

Ungültige Boards:

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

Für weitere Testfälle können Sie dieses CJam-Skript verwenden, das eine gültige Karte als Eingabe verwendet und diese zufällig mischt, um eine neue gültige Karte zu erhalten (Eingabeformat irrelevant, solange es nur Ziffern und optional Leerzeichen enthält).

Wenn Ihr regulärer Ausdruck mit der .NET-Version kompatibel ist, können Sie ihn online mit Retina testen . Eine gültige Lösung sollte 0für ungültige Karten und eine positive Ganzzahl für gültige Karten gedruckt werden. Um alle Testfälle gleichzeitig auszuführen, verwenden Sie diese Vorlage und fügen Sie den regulären Ausdruck in die zweite Zeile ein. Wenn Sie Regex-Modifikatoren benötigen, stellen Sie dem Regex ein `voran und stellen Sie die Standard-Modifikatorbuchstaben voran.



1
Wenn das nur [Code-Bowling] wäre, lol.
mbomb007

Warten Sie ... Wenn wir Python verwenden, können wir nur reguläre Ausdrücke verwenden und sonst nichts? Wie groß ist jedes Board? Gibt es eine bestimmte Größe? Wenn nicht, wie sollen wir jedes Brett aus dem Zahlenklumpen darunter extrahieren valid boards?
R. Kap

@ R.Kap Unabhängig davon, welche Variante Sie verwenden, sollten Sie nur den regulären Ausdruck (und möglicherweise einige Modifikatoren) angeben, ja. Jeder Eingang ist genau 81-stellig und repräsentiert eine Vollpension. (Jede Zeile in den Testfällen ist ein separates Board.)
Martin Ender

Ich habe ein Skript geschrieben, um einfache Sudokus in SQL zu lösen. Ich bin sicher, dass es für diese Frage umgeschrieben werden kann. SQL hat jedoch nicht viel REGEX. Disqualifiziert das die Antwort? (Skript würde wahrscheinlich etwas unter 400 Zeichen sein)
t-clausen.dk

Antworten:


40

Ruby Regex, 71 78 73 Bytes

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

Ich kenne Ruby nicht wirklich, aber anscheinend beklagt er sich nicht über kaskadierte Quantifizierer.

Probieren Sie es hier aus.

.NET Regex, 79 78 75 oder 77 Bytes

Weil Martin glaubt, dass dies möglich ist ... Aber ich denke, er wird diese Änderungen auch einbeziehen.

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

Erfordert eine abschließende neue Zeile in der Eingabe, um zu funktionieren. Ich bin mir nicht sicher, ob ich das darf (wahrscheinlich nicht).

Probieren Sie es hier aus.

Die 77-Byte-Sane-Version:

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

Vielen Dank, Neil, dass du auf den Fehler in meiner vorherigen Version hingewiesen und 1 Byte (für die (...)*) abgehoben hast .

Probieren Sie es hier aus.

PCRE, 77 78 Bytes

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

Nur der Vollständigkeit halber.

Probieren Sie es hier aus.

Eine andere Version, auch 78 Bytes:

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

Probieren Sie es hier aus.

Erläuterung

^(?!.*                    # 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.
)

Wow, gute Arbeit. Ich habe es in .NET nur auf 83 geschafft und musste für 78 auf PCRE umsteigen. :)
Martin Ender

@ MartinBüttner Ja.
Nic Hartley

Ich dachte, meine Verwendung von Lookahead, um @ MartinBüttner (zu der Zeit) um 4 Bytes zu schlagen, war ordentlich, aber Sie haben das auf die nächste Ebene gebracht.
Neil

Es tut uns leid, aber dies erkennt nicht, ob die Zellen bei (1, 2) und (2, 1) gleich sind, und dies gilt auch für alle anderen Zellen in Quadraten, in denen sich das Duplikat unten und links befindet.
Neil

1
@ MartinBüttner Ich habe gerade festgestellt, dass ich meine zweite PCRE-Version in Ruby übersetzen kann ... Ich denke, Sie können Ihre Antwort jetzt
posten

34

PCRE, 117 119 130 133 147 Bytes

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

Sollte auch in Python, Java usw. funktionieren. Jetzt mit Rekursion! Und die "Rekursion" -Funktion wurde nicht rekursiv für "Unterprogramme" verwendet, die ich völlig vergessen habe, bis ich die eigentliche Rekursion verwenden musste.


Coole Idee - Vermeiden Sie Wiederholungen, anstatt Norepeats zuzuordnen!
Qwertiy

1
Es ist eine Schande, dass Sie nicht schreiben können .{27}*.
Neil

Bah, ich hatte Ihre 133 - Byte - Lösung golfed bis zu 121 Bytes nur feststellen , dass Sie es neu geschrieben würde, aber hier ist es trotzdem:^(?!(.{27})*(.{9})?(...){0,2}.?.?(.).?.?(?=(...)*$)(.{9})?.{6,8}\4.{0,17}(.{27})*$|.*(.)((.{9})+|((?!(.{9})*$).)+)(<=\8))
Neil

@Neil Was für ein Geschmack ist das? PCRE oder andere, die ich kenne, erlauben keine Rückverweise in einem Lookbehind.
Feersum

@Neil (<=\8)sieht nicht nach gültiger Syntax aus (es fehlt ein ?). Die einzige mir bekannte Variante, die Rückverweise in Lookbehinds unterstützt, ist .NET.
Martin Ender

15

.NET regulärer Ausdruck, 8339 Bytes

Ja, ich weiß, dass meine Lösung sehr naiv ist, da Martin mir sagte, dass er sie in 130 Bytes gemacht hat. Tatsächlich ist die URL, um es online zu testen, so lang, dass ich keinen URL-Shortener finden konnte, der dies akzeptieren würde.

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

Der folgende Link funktioniert nicht in IE, funktioniert aber in Chrome und Firefox.

Online ausprobieren - Alle Testfälle auf einmal, mit Hilfe von!`zu Beginn, nicht in der Byteanzahl enthalten.


Hier ist das Python-Skript, mit dem ich es generiert habe (Code unten):

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)

1
Ich bin für Sie verwurzelt
Martijn

4
Weißt du was lustig ist? Der Online - Link "try it" stürzt ab, weil er zu lang ist: P
cat

15
@cat Aus diesem Grund erlaubt der IE dem Benutzer nur, Firefox (oder Chromium) herunterzuladen.
Byte Commander

2
@cat IE11 stürzt unter Windows 8.1 nicht ab, obwohl der Regex nicht richtig verarbeitet wird.
Nzall

2
@cat Mein IE 11 stürzt unter Windows 7 nicht ab. Die URL wird nur gekürzt.
mbomb007

14

.NET regulärer Ausdruck, 121 Byte

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

Erläuterung:

^(?!                     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
)

Schön, Ihre Kombination aus Zeilen und Spalten ist ziemlich clever. Das spart 4 Bytes bei meiner eigenen Lösung. :)
Martin Ender

8

PCRE, 3579 Bytes

Eine absolut schreckliche Brute-Force-Lösung. Negative Lookbehinds ahoi!

Ich habe viel zu viel Zeit darauf verwendet, um es aufzugeben, also ist es hier, um der Nachwelt willen.

Auf der positiven Seite, wenn Sudoku plötzlich einen anderen Satz von 9 Zeichen verwendet, funktioniert das immer noch, denke ich ...

http://pastebin.com/raw/CwtviGkC

Ich weiß nicht, wie man Retina bedient, aber Sie können es auch in https://regex101.com oder ähnliches einfügen und es wird passen.

Ruby-Code zum Generieren der 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

8

Ruby-Geschmack, 75 74 Bytes

Danke an jimmy23013 für das Speichern von 1 Byte.

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

Teste es hier.

Jetzt, wo es endlich geschlagen ist, kann ich meine eigene Lösung teilen. :) Ich habe dabei eine interessante (vielleicht neue?) Regex-Technik entdeckt (das (.|(.)){,8}\3Teil), die wahrscheinlich unschlagbar wäre, wenn dies nicht mit anderen Regex-Teilen kombiniert werden kann (wie es in der Antwort von jimmy23013 der Fall war). .

Erläuterung

Wie die anderen kurzen Antworten verwende ich einen negativen Lookahead, der nach Duplikaten in Zeilen, Spalten oder Blöcken sucht. Der Grundbaustein der Lösung ist:

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

Beachten Sie, dass die \3zwischen drei verschiedenen Alternativen wiederverwendet wird (die alle Gruppen 3für die Duplikaterkennung verwenden).

Diese Gruppe auf der linken Seite (dh Gruppe 2, die Gruppe enthält 3) wird für jede Position verwendet, die die erste Hälfte einer doppelten Ziffer enthalten kann (innerhalb einer Gruppe, die keine doppelten Ziffern enthalten darf). Dann ...ist etwas, das uns die nächste Position gibt, an der eine solche Ziffer auftreten könnte (falls erforderlich) und \3versucht, die zweite Hälfte des Duplikats über die Rückreferenz zu finden. Der Grund dafür ist das Zurückverfolgen. Wenn der Motor zum ersten Mal übereinstimmt (.|(.)), wird er einfach .jedes Mal verwendet und erfasst nichts. Jetzt \3versagt das am Ende. Aber jetzt wird der Motor nach und nach versuchen , mit (.)statt .für einzelne Spiele. Wenn es ein Duplikat gibt, findet es letztendlich die Kombination wo(.)wurde zuletzt für die erste Ziffer des Duplikats verwendet (sodass die Erfassung später nicht überschrieben wird) und verwendet dann mehr ., um die Lücke zur Rückreferenz zu schließen. Wenn es ein Duplikat gibt, wird es bei der Rückverfolgung immer gefunden.

Schauen wir uns die drei verschiedenen Teile an, in denen dies verwendet wird:

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

Dadurch wird in einigen Zeilen nach Duplikaten gesucht. Zuerst springen wir zu einer Zeile mit .{9}*. Dann vergleichen wir bis zu 8 Zeichen (dh alles in dieser Zeile mit Ausnahme der letzten Ziffer) mit der optionalen doppelten Erfassung und versuchen, das \3dahinter stehende zu finden .

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

Dies sucht in einigen Spalten nach Duplikaten. Beachten Sie zunächst, dass dies \g<2>ein Unterprogrammaufruf ist. Dies ist also dasselbe wie:

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

wo die zwei Gruppen, die wir gerade eingefügt haben, noch als 2und bezeichnet werden 3.

Hier .*springt das einfach so weit wie nötig (es würde ausreichen, hier bis zu 8 Zeichen zu finden, aber das kostet mehr Bytes). Dann stimmt die äußere Gruppe mit jeweils einer vollständigen Zeile überein (die sich über zwei physische Zeilen erstrecken kann), wobei optional das erste Zeichen erfasst wird. Das \3wird für die direkt nach diesen gesucht werden, die zwischen der Aufnahme und dem Rückreferenzierung vertikale Ausrichtung gewährleistet.

Überprüfen Sie abschließend die Blöcke:

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

Auch hier \g<2>handelt es sich um einen Unterprogrammaufruf. Dies ist also dasselbe wie:

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

Beachten Sie zur Überprüfung der Blöcke, dass wir, da wir bereits alle Zeilen und Spalten überprüft haben, nur vier der 3x3-Blöcke überprüfen müssen. Wenn wir wissen, dass alle Zeilen und Spalten sowie diese 3x3-Blöcke korrekt sind:

XX.
XX.
...

Dann wissen wir, dass es in den verbleibenden Blöcken möglicherweise keine Duplikate geben kann. Daher überprüfe ich nur diese vier Blöcke. Beachten Sie außerdem, dass wir nicht in derselben Zeile eines 3x3-Blocks nach Duplikaten suchen müssen. Es reicht aus, die erste Hälfte des Duplikats in einer Reihe zu finden und die zweite Hälfte in einer Reihe weiter unten zu suchen.

Für den Code selbst springen wir zunächst zum Anfang eines der vier Blöcke mit .{27}?.{3}?(optional drei Zeilen überspringen, optional drei Spalten überspringen). Dann versuchen wir, bis zu zwei der Zeilen des 3x3-Blocks mit demselben Trick abzugleichen, den wir zuvor für die Zeilen verwendet haben:

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

Wir erlauben, müssen aber keine der 3 Zellen in der aktuellen Zeile des 3x3-Blocks erfassen und dann mit in die nächste Zeile springen .{6}. Schließlich versuchen wir, in einer der drei Zellen der Zeile, in der wir landen, ein Duplikat zu finden:

.?.?

Und das ist es.


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 Ich habe den \4()Trick in einer früheren Version für die 3x3-Blöcke verwendet, bin ihn aber am Ende losgeworden, weil er länger war. : D
Martin Ender

@ jimmy23013 Der 73er prüft die letzte Reihe allerdings nicht:341572689257698143986413275862341957495726831173985426519234768734869512628517394
Martin Ender

6

Javascript regex, 532 530 481 463 Zeichen

Zeilen validieren:

/^((?=.{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})+$/

Spalten validieren:

/^((?=(.{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}/

Validiere das Quadrat von seinem ersten Zeichen an:

/(?=.?.?(.{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)/

Stellen Sie die Vorschau auf den Anfang des Quadrats ein:

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

Und der ganze Ausdruck:

/^(?=((?=.{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})+$/

Entspricht der gesamten Zeichenfolge.


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

Ich denke, Spalten sollten viel einfacher sein als Zeilen, deshalb finde ich es merkwürdig, dass Ihr Spalten-Regex länger ist als Ihre erste Zeile.
Peter Taylor

@PeterTaylor, sie haben die gleiche Struktur, aber für Spalten Ich habe 9 Zeichen überspringen statt 1, so .wird in (.{9})mit Klammern wegen der nächsten {0,8}. Warum sollten die Spalten Ihrer Meinung nach kürzer sein?
Qwertiy

@PeterTaylor, yep, Spalten wären einfacher gewesen, wenn ich die Negation überprüft hätte.
Qwertiy

@ SuperJedi224, warum Javascript? Ich erwarte, dass dieser reguläre Ausdruck überall gültig ist.
Qwertiy

6
@Qwertiy Während Ihre Regex in vielen Varianten funktionieren sollte, stützt sie sich auf Lookaheads (z. B. nicht in Lua oder OCaml verfügbar). Es ist auch ein ungültiger regulärer Basis- oder erweiterter Ausdruck, der eine völlig andere Syntax verwendet. Es ist am besten, für den Gültigkeitsanspruch Geschmack zu wählen, auch wenn die Lösung in vielen anderen Fällen funktioniert.
Dennis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.