Możesz użyć do tego następującego wyrażenia regularnego:
^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
Rozbijając go, M{0,4}
określa sekcję tysięcy i zasadniczo ogranicza go do między 0
a 4000
. To stosunkowo proste:
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}
Możesz oczywiście użyć czegoś w rodzaju, M*
aby zezwolić na dowolną liczbę (w tym zero) tysięcy, jeśli chcesz zezwolić na większe liczby.
Dalej (CM|CD|D?C{0,3})
, nieco bardziej skomplikowane, dotyczy sekcji setki i obejmuje wszystkie możliwości:
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
Po trzecie, obowiązuje (XC|XL|L?X{0,3})
te same zasady, co poprzednia sekcja, ale dla miejsca dziesiątek:
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
I wreszcie, (IX|IV|V?I{0,3})
jest sekcja jednostki, obsługa 0
przez 9
i podobne do dwóch poprzednich odcinków (cyfry rzymskie, pomimo ich pozornej tajemniczości, przestrzegać pewnych reguł logicznych Po dowiedzieć się, jakie są):
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
Pamiętaj tylko, że to wyrażenie regularne będzie również pasowało do pustego ciągu. Jeśli tego nie chcesz (a Twój silnik wyrażeń regularnych jest wystarczająco nowoczesny), możesz zastosować pozytywne spojrzenie w tył i w przyszłość:
(?<=^)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})(?=$)
(inną alternatywą jest po prostu sprawdzenie, czy długość nie wynosi wcześniej zero).
MMMM
była właściwa droga. Reprezentacja overbar pojawiła się długo po rozpadzie imperium./^M{0,3}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})$/i
Właściwie twoje założenie jest błędne. 990 IS „XM”, a także „CMXC”.
Rzymianie byli o wiele mniej zaniepokojeni „zasadami” niż nauczyciel z trzeciej klasy. Dopóki to się zgadzało, było OK. Stąd „IIII” było tak samo dobre jak „IV” za 4. A „IIM” było zupełnie fajne dla 998.
(Jeśli masz z tym problem ... Pamiętaj, że pisownia angielska została sformalizowana dopiero w XVIII wieku. Do tego czasu, o ile czytelnik mógł to zrozumieć, była wystarczająco dobra).
źródło
Wystarczy zapisać go tutaj:
Pasuje do wszystkich cyfr rzymskich. Nie przejmuje się pustymi ciągami (wymaga co najmniej jednej litery rzymskiej). Powinien działać w PCRE, Perl, Python i Ruby.
Demo online Rubiego: http://rubular.com/r/KLPR1zq3Hj
Konwersja online: http://www.onlineconversion.com/roman_numerals_advanced.htm
źródło
Aby uniknąć dopasowania pusty łańcuch trzeba powtórzyć wzór o cztery razy i zastąpić każdy
0
z1
kolei, a na kontoV
,L
iD
:W tym przypadku (ponieważ ten wzorzec używa
^
i$
) lepiej byłoby najpierw sprawdzić puste wiersze i nie zawracać sobie głowy dopasowywaniem ich. Jeśli używasz granic słów , nie masz problemu, ponieważ nie ma czegoś takiego jak puste słowo. (Przynajmniej regex nie definiuje żadnego; nie zaczynaj filozofowania, jestem tutaj pragmatyczny!)W moim konkretnym przypadku (w prawdziwym świecie) potrzebowałem dopasowywania cyfr na końcówkach słów i nie znalazłem innego sposobu na obejście tego. Musiałem peeling off numery przypisów z mojego zwykłego dokumentu tekstowego, gdzie tekst takich jak „Red Sea cl i Wielkiej Rafy Koralowej CLI ” zostało przekształcone w
the Red Seacl and the Great Barrier Reefcli
. Ale nadal miałem problemy z ważnymi słowami, takimi jakTahiti
ifantastic
są przenoszone doTahit
ifantasti
.źródło
M
lubC
czyL
, tak, masz to rodzaj uproszczonego wyrażenia regularnego?(X{1,3}(IX|IV|V?I{0,3})|X{0,3}(IX|I?V|V?I{1,3}))
Na szczęście zakres numerów jest ograniczony do 1–3999 lub mniej więcej. W związku z tym możesz zbudować regex kawałek-posiłek.
Każda z tych części będzie dotyczyła kaprysów notacji rzymskiej. Na przykład używając notacji Perl:
Powtórz i złóż.
Dodano :
<opt-hundreds-part>
Można dalej skompresować:Ponieważ klauzula „D? C {0,3}” nie może niczego dopasować, nie ma potrzeby wstawiania znaku zapytania. Najprawdopodobniej nawiasy powinny być typu nieprzechwytywania - w Perlu:
Oczywiście we wszystkich również powinna być rozróżniana wielkość liter.
Możesz również rozszerzyć to, aby poradzić sobie z opcjami wymienionymi przez Jamesa Currana (aby zezwolić na XM lub IM dla 990 lub 999 i CCCC dla 400 itd.).
źródło
thousands hundreds tens units
, łatwo jest stworzyć FSM, który oblicza i weryfikuje podane cyfry rzymskieDla osób, które naprawdę chcą zrozumieć logikę, zapoznaj się z wyjaśnieniem krok po kroku na 3 stronach na temat diveintopython .
Jedyna różnica w stosunku do oryginalnego rozwiązania (które miało
M{0,4}
) polega na tym, że stwierdziłem, że „MMMM” nie jest poprawną cyfrą rzymską (również starzy Rzymianie prawdopodobnie nie myśleli o tej ogromnej liczbie i nie zgodzą się ze mną). Jeśli nie zgadzasz się ze starymi Rzymianami, wybacz mi i użyj wersji {0,4}.źródło
Odpowiadam na to pytanie Wyrażenie regularne w Pythonie dla liczb rzymskich ,
ponieważ zostało zaznaczone jako dokładny duplikat tego pytania.
Nazwa może być podobna, ale jest to konkretne pytanie / problem wyrażenia regularnego,
jak widać po odpowiedzi na to pytanie.
Poszukiwane elementy można połączyć w jedną zmianę, a następnie
umieścić w grupie przechwytywania, która zostanie umieszczona na liście za pomocą funkcji findall ()
.
Robi się to tak:
Modyfikacje wyrażenia regularnego w celu uwzględnienia i przechwycenia samych liczb są następujące:
źródło
Jak Jeremy i Pax wskazali powyżej ... '^ M {0,4} (CM | CD | D? C {0,3}) (XC | XL | L? X {0,3}) (IX | IV | V? I {0,3}) $ 'powinno być rozwiązaniem, którego szukasz ...
Konkretny adres URL, który powinien zostać dołączony (IMHO), to http://thehazeltree.org/diveintopython/7.html
Przykład 7.8 to krótka forma wykorzystująca {n, m}
źródło
W moim przypadku próbowałem znaleźć i zamienić wszystkie wystąpienia liczb rzymskich jednym słowem w tekście, więc nie mogłem użyć początku i końca linii. Zatem rozwiązanie @paxdiablo znalazło wiele dopasowań o zerowej długości. Skończyło się na następującym wyrażeniu:
Mój ostateczny kod w Pythonie wyglądał następująco:
Wynik:
źródło
Steven Levithan używa tego wyrażenia regularnego w swoim poście, który weryfikuje cyfry rzymskie przed „deromanizacją” wartości:
źródło
Widziałem wiele odpowiedzi, które nie obejmują pustych ciągów ani nie używają lookaheads do rozwiązania tego problemu. Chcę dodać nową odpowiedź, która obejmuje puste łańcuchy i nie używa antycypowania. Wyrażenie regularne jest następujące:
^(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}))$
Pozwalam na nieskończoność
M
,M+
ale oczywiście ktoś może się zmienićM{1,4}
aby zezwolić tylko na 1 lub 4 w razie potrzeby.Poniżej znajduje się wizualizacja, która pomaga zrozumieć, co robi, poprzedzona dwoma demonstracjami online:
Debuggex Demo
Regex 101 Demo
źródło
Działa to w silnikach regex Java i PCRE i powinno teraz działać w najnowszym JavaScript, ale może nie działać we wszystkich kontekstach.
(?<![A-Z])(M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3}))(?![A-Z])
Pierwsza część to potworne negatywne spojrzenie za siebie. Ale ze względów logicznych jest to najłatwiejsze do zrozumienia. Zasadniczo pierwsze
(?<!)
mówi, że nie dopasowuj środka,([MATCH])
jeśli przed środkiem są litery,([MATCH])
a ostatnie(?!)
mówi, że nie dopasowuj środka,([MATCH])
jeśli są po nim litery.Środek
([MATCH])
jest po prostu najczęściej używanym wyrażeniem regularnym do dopasowywania sekwencji liczb rzymskich. Ale teraz nie chcesz dopasować tego, jeśli wokół niego są jakieś litery.Sam zobacz. https://regexr.com/4vce5
źródło
Problem rozwiązania Jeremy'ego i Paxa polega na tym, że pasuje ono również do „niczego”.
Następujące wyrażenie regularne wymaga co najmniej jednej cyfry rzymskiej:
źródło
|
może pasować do pustego ciągu i wszystkich prawidłowych cyfr rzymskich, więc prawa strona jest całkowicie zbędna. i tak, nadal pasuje do pustego ciągu.Pisałbym dla mnie funkcje do mojej pracy. Oto dwie funkcje liczb rzymskich w programie PowerShell.
źródło