Sie können hierfür den folgenden regulären Ausdruck verwenden:
^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
Wenn Sie es aufschlüsseln, wird M{0,4}
der Abschnitt mit den Tausenden angegeben und im Grunde genommen auf zwischen 0
und beschränkt 4000
. Es ist relativ einfach:
0: <empty> matched by M{0}
1000: M matched by M{1}
2000: MM matched by M{2}
3000: MMM matched by M{3}
4000: MMMM matched by M{4}
Sie können natürlich M*
eine beliebige Zahl (einschließlich Null) von Tausenden zulassen, wenn Sie größere Zahlen zulassen möchten.
Als nächstes ist (CM|CD|D?C{0,3})
etwas komplexer, dies ist für den Hunderte-Abschnitt und deckt alle Möglichkeiten ab:
0: <empty> matched by D?C{0} (with D not there)
100: C matched by D?C{1} (with D not there)
200: CC matched by D?C{2} (with D not there)
300: CCC matched by D?C{3} (with D not there)
400: CD matched by CD
500: D matched by D?C{0} (with D there)
600: DC matched by D?C{1} (with D there)
700: DCC matched by D?C{2} (with D there)
800: DCCC matched by D?C{3} (with D there)
900: CM matched by CM
Drittens (XC|XL|L?X{0,3})
folgt den gleichen Regeln wie im vorherigen Abschnitt, jedoch für die Zehnerstelle:
0: <empty> matched by L?X{0} (with L not there)
10: X matched by L?X{1} (with L not there)
20: XX matched by L?X{2} (with L not there)
30: XXX matched by L?X{3} (with L not there)
40: XL matched by XL
50: L matched by L?X{0} (with L there)
60: LX matched by L?X{1} (with L there)
70: LXX matched by L?X{2} (with L there)
80: LXXX matched by L?X{3} (with L there)
90: XC matched by XC
Und schließlich (IX|IV|V?I{0,3})
ist die Einheiten Abschnitt, Handhabung 0
durch 9
und auch ähnlich wie die beiden vorherigen Abschnitte (römische Ziffern, trotz ihrer scheinbaren Seltsamkeit, folgen einigen logischen Regeln , wenn Sie herausfinden , was sie sind):
0: <empty> matched by V?I{0} (with V not there)
1: I matched by V?I{1} (with V not there)
2: II matched by V?I{2} (with V not there)
3: III matched by V?I{3} (with V not there)
4: IV matched by IV
5: V matched by V?I{0} (with V there)
6: VI matched by V?I{1} (with V there)
7: VII matched by V?I{2} (with V there)
8: VIII matched by V?I{3} (with V there)
9: IX matched by IX
Denken Sie daran, dass dieser reguläre Ausdruck auch mit einer leeren Zeichenfolge übereinstimmt. Wenn Sie dies nicht möchten (und Ihre Regex-Engine modern genug ist), können Sie positive Rückblicke und Vorausschau verwenden:
(?<=^)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})(?=$)
(Die andere Alternative besteht darin, vorher zu überprüfen, ob die Länge nicht Null ist).
MMMM
war der richtige Weg. Die Overbar-Darstellung erfolgte lange nachdem das Kernimperium in Stücke gefallen war./^M{0,3}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})$/i
Tatsächlich ist Ihre Prämisse fehlerhaft. 990 IS "XM" sowie "CMXC".
Die Römer waren weit weniger besorgt über die "Regeln" als Ihr Lehrer der dritten Klasse. Solange es sich summierte, war es in Ordnung. Daher war "IIII" für 4 genauso gut wie "IV". Und "IIM" war für 998 völlig cool.
(Wenn Sie Probleme damit haben ... Denken Sie daran, dass englische Schreibweisen erst im 18. Jahrhundert formalisiert wurden. Bis dahin war es gut genug, solange der Leser es herausfinden konnte.)
quelle
Nur um es hier zu speichern:
Entspricht allen römischen Ziffern. Kümmert sich nicht um leere Zeichenfolgen (erfordert mindestens einen römischen Ziffernbuchstaben). Sollte in PCRE, Perl, Python und Ruby funktionieren.
Online Ruby-Demo: http://rubular.com/r/KLPR1zq3Hj
Online-Konvertierung: http://www.onlineconversion.com/roman_numerals_advanced.htm
quelle
Um zu vermeiden , den leeren String - Matching müssen Sie das Muster viermal wiederholen und ersetzen jeweils
0
mit einem1
wiederum und machenV
,L
undD
:In diesem Fall (da dieses Muster
^
und verwendet$
) sollten Sie zuerst nach leeren Zeilen suchen und sich nicht die Mühe machen, diese abzugleichen. Wenn Sie Wortgrenzen verwenden, haben Sie kein Problem, da es kein leeres Wort gibt. (Zumindest definiert Regex keinen; fang nicht an zu philosophieren, ich bin hier pragmatisch!)In meinem speziellen Fall (in der realen Welt) brauchte ich übereinstimmende Ziffern an den Wortenden und fand keinen anderen Weg daran vorbei. Ich musste die Fußnotennummern aus meinem Nur-Text-Dokument entfernen , in das Text wie "Red Sea Cl und Great Barrier Reef Cli " konvertiert worden war
the Red Seacl and the Great Barrier Reefcli
. Aber ich hatte immer noch Probleme mit gültigen Wörtern wieTahiti
und werdefantastic
inTahit
und geschrubbtfantasti
.quelle
M
oderC
oderL
haben Sie dies? Art von vereinfachtem Regex?(X{1,3}(IX|IV|V?I{0,3})|X{0,3}(IX|I?V|V?I{1,3}))
Glücklicherweise ist der Zahlenbereich auf ungefähr 1..3999 begrenzt. Daher können Sie das Regex-Stückgericht aufbauen.
Jeder dieser Teile wird sich mit den Launen der römischen Notation befassen. Beispiel: Verwenden der Perl-Notation:
Wiederholen und zusammenbauen.
Hinzugefügt : Das
<opt-hundreds-part>
kann weiter komprimiert werden:Da die Klausel 'D? C {0,3}' mit nichts übereinstimmen kann, ist das Fragezeichen nicht erforderlich. Und höchstwahrscheinlich sollten die Klammern vom Typ ohne Erfassung sein - in Perl:
Natürlich sollte auch die Groß- und Kleinschreibung nicht berücksichtigt werden.
Sie können dies auch erweitern, um die von James Curran genannten Optionen zu behandeln (um XM oder IM für 990 oder 999 und CCCC für 400 usw. zuzulassen).
quelle
thousands hundreds tens units
ist es einfach , einen FSMFür Leute, die die Logik wirklich verstehen wollen, lesen Sie bitte eine schrittweise Erklärung auf 3 Seiten über Diveintopython .
Der einzige Unterschied zur ursprünglichen Lösung (die es gab
M{0,4}
) besteht darin, dass ich festgestellt habe, dass 'MMMM' keine gültige römische Ziffer ist (auch alte Römer haben höchstwahrscheinlich nicht über diese große Zahl nachgedacht und werden mir nicht zustimmen). Wenn Sie nicht mit alten Römern übereinstimmen, verzeihen Sie mir bitte und verwenden Sie die Version {0,4}.quelle
Ich beantworte diese Frage Regulärer Ausdruck in Python für römische Ziffern hier,
weil er als genaues Duplikat dieser Frage markiert wurde.
Der Name mag ähnlich sein, aber dies ist eine spezifische Regex-Frage / ein Problem,
wie aus dieser Antwort auf diese Frage hervorgeht.
Die gesuchten Elemente können zu einer einzigen Abwechslung zusammengefasst und dann
in eine Erfassungsgruppe eingeschlossen werden, die mit der
Funktion findall () in eine Liste aufgenommen wird .
Es wird so gemacht:
Die Regex-Modifikationen zum Faktorisieren und Erfassen nur der Ziffern lauten wie folgt:
quelle
Wie Jeremy und Pax oben ausgeführt haben ... '^ M {0,4} (CM | CD | D? C {0,3}) (XC | XL | L? X {0,3}) (IX | IV | V? I {0,3}) $ 'sollte die Lösung sein, nach der Sie suchen ...
Die spezifische URL, die angehängt werden sollte (IMHO), lautet http://thehazeltree.org/diveintopython/7.html
Beispiel 7.8 ist die Kurzform mit {n, m}
quelle
In meinem Fall habe ich versucht, alle Vorkommen römischer Zahlen durch ein Wort im Text zu finden und zu ersetzen, sodass ich den Anfang und das Ende von Zeilen nicht verwenden konnte. Die @ paxdiablo-Lösung hat also viele Übereinstimmungen mit der Länge Null gefunden. Am Ende hatte ich folgenden Ausdruck:
Mein letzter Python-Code war wie folgt:
Ausgabe:
quelle
Steven Levithan verwendet diesen regulären Ausdruck in seinem Beitrag, der römische Ziffern validiert, bevor der Wert "deromanisiert" wird:
quelle
Ich habe mehrere Antworten gesehen, die keine leeren Zeichenfolgen abdecken oder Lookaheads verwenden, um dies zu lösen. Und ich möchte eine neue Antwort hinzufügen, die leere Zeichenfolgen abdeckt und keinen Lookahead verwendet. Der reguläre Ausdruck ist der folgende:
^(I[VX]|VI{0,3}|I{1,3})|((X[LC]|LX{0,3}|X{1,3})(I[VX]|V?I{0,3}))|((C[DM]|DC{0,3}|C{1,3})(X[LC]|L?X{0,3})(I[VX]|V?I{0,3}))|(M+(C[DM]|D?C{0,3})(X[LC]|L?X{0,3})(I[VX]|V?I{0,3}))$
Ich erlaube unendlich
M
,M+
aber natürlich könnte jemand ändernM{1,4}
, um nur 1 oder 4 zuzulassen, wenn dies gewünscht wird.Im Folgenden finden Sie eine Visualisierung, die Ihnen hilft, die Funktionsweise zu verstehen. Vorangegangen sind zwei Online-Demos:
Debuggex-Demo
Regex 101 Demo
quelle
Dies funktioniert in Java- und PCRE-Regex-Engines und sollte jetzt im neuesten JavaScript funktionieren, funktioniert jedoch möglicherweise nicht in allen Kontexten.
(?<![A-Z])(M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3}))(?![A-Z])
Der erste Teil ist das grausame negative Aussehen. Aus logischen Gründen ist es jedoch am einfachsten zu verstehen. Grundsätzlich
(?<!)
sagt der erste, dass er nicht mit der Mitte übereinstimmt,([MATCH])
wenn Buchstaben vor der Mitte stehen,([MATCH])
und der letzte(?!)
sagt, dass er nicht mit der Mitte übereinstimmt([MATCH])
wenn Buchstaben danach kommen.Die Mitte
([MATCH])
ist nur der am häufigsten verwendete Regex, um die Reihenfolge der römischen Ziffern abzugleichen. Aber jetzt wollen Sie das nicht mehr zusammenbringen, wenn es Buchstaben gibt.Überzeugen Sie sich selbst. https://regexr.com/4vce5
quelle
Das Problem der Lösung von Jeremy und Pax ist, dass sie auch mit "nichts" übereinstimmt.
Der folgende reguläre Ausdruck erwartet mindestens eine römische Ziffer:
quelle
|
kann mit einer leeren Zeichenfolge und allen gültigen römischen Ziffern übereinstimmen, sodass die rechte Seite vollständig redundant ist. und ja, es stimmt immer noch mit einer leeren Zeichenfolge überein.Ich würde Funktionen für meine Arbeit für mich schreiben. Hier sind zwei Funktionen für römische Zahlen in PowerShell.
quelle