आप एक नियमित अभिव्यक्ति के साथ केवल वैध रोमन अंकों से कैसे मेल खाते हैं?


165

मेरी अन्य समस्या के बारे में सोचते हुए , मैंने फैसला किया कि मैं एक नियमित अभिव्यक्ति भी नहीं बना सकता हूँ जो रोमन अंकों से मेल खाए (अकेले एक संदर्भ-मुक्त व्याकरण जो उन्हें उत्पन्न करेगा)

समस्या केवल मान्य रोमन अंकों से मेल खा रही है। जैसे, 990 "एक्सएम" नहीं है, यह "सीएमएक्ससी" है

इसके लिए रेगेक्स बनाने में मेरी समस्या यह है कि कुछ पात्रों को अनुमति देने या न देने के लिए, मुझे पीछे देखने की जरूरत है। उदाहरण के लिए, हजारों और सैकड़ों लेते हैं।

मैं M {0,2} C? M की अनुमति दे सकता हूं (900, 1000, 1900, 2000, 2900 और 3000 के लिए अनुमति देने के लिए)। हालाँकि, यदि मैच सीएम पर है, तो मैं निम्नलिखित पात्रों को C या D होने की अनुमति नहीं दे सकता (क्योंकि मैं पहले से ही 900 पर हूं)।

मैं इसे regex में कैसे व्यक्त कर सकता हूं?
यदि यह केवल एक रेगेक्स में व्यक्त नहीं है, तो क्या यह एक संदर्भ-मुक्त व्याकरण में व्यक्त किया जा सकता है?

जवाबों:


328

आप इसके लिए निम्न regex का उपयोग कर सकते हैं:

^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$

इसे तोड़कर, M{0,4}हजारों खंड को निर्दिष्ट करता है और मूल रूप से इसके बीच में 0और इसे नियंत्रित करता है 4000। यह अपेक्षाकृत सरल है:

   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}

तुम्हें पता है, ज़ाहिर है, कुछ की तरह इस्तेमाल कर सकते हैं M*अनुमति देने के लिए किसी भी हजारों की (शून्य सहित), अगर आप बड़ी संख्या की अनुमति देना चाहते संख्या।

अगला (CM|CD|D?C{0,3}), थोड़ा और अधिक जटिल है, यह सैकड़ों अनुभागों के लिए है और सभी संभावनाओं को शामिल करता है:

  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

तीसरा, (XC|XL|L?X{0,3})पिछले अनुभाग के समान नियम लेकिन दसियों स्थान के लिए निम्न प्रकार है:

 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

और अंत में, (IX|IV|V?I{0,3})इकाइयों अनुभाग, हैंडलिंग है 0के माध्यम से 9और इसने पिछले दो वर्गों (रोमन अंकों, उनके प्रतीयमान weirdness के बावजूद, कुछ तार्किक नियमों का पालन एक बार आप यह पता लगाने के लिए वे क्या कर रहे हैं) के लिए इसी तरह:

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

बस ध्यान रखें कि रेगेक्स एक खाली स्ट्रिंग से भी मेल खाएगा। यदि आप यह नहीं चाहते (और आपका रेगेक्स इंजन पर्याप्त आधुनिक है), तो आप सकारात्मक लुक-बैक और लुक-फॉरवर्ड का उपयोग कर सकते हैं:

(?<=^)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})(?=$)

(सिर्फ दूसरा विकल्प होने की जाँच करें कि लंबाई पहले से शून्य नहीं है)।


12
क्या यह M {0,3} नहीं होना चाहिए?
नींबू

3
खाली स्ट्रिंग के मिलान से बचने का कोई उपाय?
फेसुंडो कैस्को

11
@ आशीष: जब रोमियों के साथ फिर से होने के लिए एक बल MMMMथा, सही तरीका था। ओवरबार प्रतिनिधित्व लंबे समय बाद आया जब कोर साम्राज्य टुकड़े-टुकड़े हो गया।
पैक्सिडाब्लो

2
@paxdiablo यह है कि मैंने पाया कि mmmcm कैसे विफल होता है। स्ट्रिंग regx = "^ M {0,3} (CM | CD | D; C {0,3}) (XC; XL | L | X {0,3}) (IX | IV | V | I I 0) | 3}) $ "; अगर (input.matches (regx)) -> यह जावा में MMMCM / MMMM के लिए गलत है।
14

2
/^M{0,3}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})$/i
क्रिस्सोव

23

दरअसल, आपका आधार त्रुटिपूर्ण है। 990 आईएस "एक्सएम", साथ ही "सीएमएक्ससी" है।

रोमन आपके तृतीय श्रेणी शिक्षक की तुलना में "नियमों" के बारे में बहुत कम चिंतित थे। जब तक यह जोड़ा गया, यह ठीक था। 4. "IIII" 4. के लिए "IV" जितना ही अच्छा था और 998 के लिए "IIM" पूरी तरह से ठंडा था।

(यदि आपको इससे निपटने में परेशानी होती है ... याद रखें कि अंग्रेजी वर्तनी 1700 तक औपचारिक नहीं थी। तब तक, जब तक पाठक इसका पता लगा सकते थे, यह काफी अच्छा था।)


8
यकीन है, यह अच्छा है। लेकिन मेरी "सख्त तृतीय श्रेणी शिक्षक" वाक्यविन्यास की जरूरत मेरे विचार में एक बहुत अधिक दिलचस्प रेगेक्स समस्या बनाती है ...
डैनियल मैगियोला

5
अच्छा बिंदु जेम्स, एक सख्त लेखक लेकिन एक क्षमाशील पाठक होना चाहिए।
कोरिन


13

बस इसे यहाँ बचाने के लिए:

(^(?=[MDCLXVI])M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$)

सभी रोमन अंकों से मेल खाता है। खाली तारों की परवाह नहीं करता (कम से कम एक रोमन अंक पत्र की आवश्यकता होती है)। PCRE, पर्ल, पायथन और रूबी में काम करना चाहिए।

ऑनलाइन रूबी डेमो: http://rubular.com/r/KLPR1zq3Hj

ऑनलाइन रूपांतरण: http://www.onlineconversion.com/roman_numeral_advanced.htm


2
मुझे पता नहीं क्यों, लेकिन मुख्य उत्तर मेमोक्यू में ऑटोट्रांसलेट सूची में मेरे लिए काम नहीं किया। हालाँकि, यह समाधान करता है - हालांकि स्ट्रिंग स्टार्ट / एंड सिंबल को छोड़कर।
orlando2bjr

1
@ orlando2bjr मदद करने के लिए खुश है। हाँ, इस मामले में मैं अपने आप में एक नंबर मिलान कर रहा था, बिना परिवेश के। यदि आप इसे किसी पाठ में खोजते हैं, तो निश्चित रूप से आपको ^ $ निकालने की आवश्यकता होगी। चीयर्स!
smileart

12

खाली स्ट्रिंग के मिलान से बचने के लिए आपको पैटर्न को चार बार दोहराना होगा और प्रत्येक 0को 1बदले में, और खाते से बदलना होगा V, Lऔर D:

(M{1,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})|M{0,4}(CM|C?D|D?C{1,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})|M{0,4}(CM|CD|D?C{0,3})(XC|X?L|L?X{1,3})(IX|IV|V?I{0,3})|M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|I?V|V?I{1,3}))

इस मामले में (क्योंकि यह पैटर्न उपयोग करता है ^और $) आप पहले खाली लाइनों के लिए जाँच करना बेहतर होगा और उन्हें मिलान करने में परेशान न करें। यदि आप शब्द सीमाओं का उपयोग कर रहे हैं तो आपको कोई समस्या नहीं है क्योंकि खाली शब्द जैसी कोई चीज नहीं है। (कम से कम रेगेक्स एक को परिभाषित नहीं करता है; दार्शनिकता शुरू न करें, मैं यहां व्यावहारिक हो रहा हूं!)


अपने स्वयं के विशेष (वास्तविक दुनिया) मामले में मुझे शब्द समाप्ति पर मैच अंकों की आवश्यकता थी और मुझे इसके आसपास कोई अन्य रास्ता नहीं मिला। मुझे अपने सादे टेक्स्ट डॉक्यूमेंट से फुटनोट नंबरों को खंगालने की ज़रूरत थी, जहाँ "रेड सी सीएल और ग्रेट बैरियर रीफ़ क्ली " जैसे टेक्स्ट को परिवर्तित कर दिया गया था the Red Seacl and the Great Barrier Reefcli। लेकिन मुझे अभी भी इस तरह के मान्य शब्दों के साथ समस्या थी Tahitiऔर fantasticइसमें स्क्रब किया जाता है Tahitऔर fantasti


मेरे पास इसी तरह की समस्या है (!): एक आइटम सूची के शेष / अवशिष्ट रोमन संख्या के "बाएं ट्रिम" करने के लिए (टाइप I या i का HTML ओएल)। इसलिए, जब वहाँ शेष रहे हैं, मैं साफ करने के लिए (एक ट्रिम समारोह की तरह) अपने रेगुलर एक्सप्रेशन के साथ मद-पाठ की शुरुआत (बाएं) पर अधिक सरल की जरूरत है ... लेकिन: आइटम का उपयोग कभी नहीं Mया Cया Lहै, तो आप इस की क्या ज़रूरत है सरलीकृत regex की तरह?
पीटर क्रूस

... ठीक है, यहाँ यह ठीक लगता है (!),(X{1,3}(IX|IV|V?I{0,3})|X{0,3}(IX|I?V|V?I{1,3}))
पीटर क्रस

1
आपको खाली तारों को अस्वीकार करने के लिए पैटर्न दोहराने की आवश्यकता नहीं है। आप हो सकता है एक अग्रदर्शी दावे का उपयोग
JFS

7

सौभाग्य से, संख्या की सीमा 1..3999 या उसके बाद तक सीमित है। इसलिए, आप रेगेक्स टुकड़ा-भोजन का निर्माण कर सकते हैं।

<opt-thousands-part><opt-hundreds-part><opt-tens-part><opt-units-part>

उन भागों में से प्रत्येक रोमन संकेतन की योनि से निपटेंगे। उदाहरण के लिए, पर्ल नोटेशन का उपयोग करना:

<opt-hundreds-part> = m/(CM|DC{0,3}|CD|C{1,3})?/;

दोहराएँ और इकट्ठा।

जोड़ा गया : <opt-hundreds-part>आगे संपीड़ित किया जा सकता है:

<opt-hundreds-part> = m/(C[MD]|D?C{0,3})/;

चूंकि 'D; C {0,3}' क्लॉज कुछ भी मैच नहीं कर सकता है, इसलिए प्रश्न चिह्न की कोई आवश्यकता नहीं है। और, सबसे अधिक संभावना है, कोष्ठक गैर-कैप्चरिंग प्रकार होना चाहिए - पर्ल में:

<opt-hundreds-part> = m/(?:C[MD]|D?C{0,3})/;

बेशक, यह सभी के लिए असंवेदनशील होना चाहिए।

जेम्स क्यूरन द्वारा उल्लिखित विकल्पों (990 या 999 के लिए एक्सएम या आईएम और 400 के लिए सीसीसीसी को अनुमति देने के लिए), आदि से निपटने के लिए आप इसे बढ़ा सकते हैं।

<opt-hundreds-part> = m/(?:[IXC][MD]|D?C{0,4})/;

thousands hundreds tens unitsइसके साथ , FSM बनाना
jfs

सौभाग्य से आपका क्या मतलब है , संख्या की सीमा १.३ ९९ या उसके स्थान तक सीमित है ? इसे किसने सीमित किया?
सेक्सीबीस्ट

@SexyBeast: 5,000 के लिए कोई मानक रोमन संकेतन नहीं है, अकेले बड़ी संख्या दें, इसलिए नियमित रूप से काम करने वाले नियमित रूप से काम करना बंद कर दें।
जोनाथन लेफ्लर 15

यकीन नहीं होता कि आप ऐसा क्यों मानते हैं, लेकिन रोमन अंक लाखों में संख्याओं का प्रतिनिधित्व कर सकते हैं। en.wikipedia.org/wiki/Roman_numeral#Large_numbers
एम्ब्रोसचैपेल

@AmbroseChapel: जैसा कि मैंने कहा, 5,000 के लिए कोई (एकल) मानक संकेतन नहीं है, अकेले बड़ी संख्या में जाने दें। आपके द्वारा लिंक किए गए विकिपीडिया लेख में उल्लिखित कई डायवर्जेंट सिस्टमों में से एक का उपयोग करना होगा, और आप सिस्टम के लिए ऑर्बोग्राफी के साथ ओवरबार्स, अंडरबार या उल्टे सी आदि के साथ समस्याओं का सामना करेंगे और आपको किसी को भी समझाना होगा कि क्या सिस्टम आप उपयोग कर रहे हैं और इसका क्या अर्थ है; लोग, सामान्य रूप से, एम से परे रोमन अंकों को नहीं पहचानेंगे। आप अन्यथा सोचना चुन सकते हैं; यह आपका विशेषाधिकार है, जैसे कि यह मेरी पिछली टिप्पणियों द्वारा खड़े होने के लिए मेरा विशेषाधिकार है।
जोनाथन लेफ्लर

7
import re
pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
if re.search(pattern, 'XCCMCI'):
    print 'Valid Roman'
else:
    print 'Not valid Roman'

उन लोगों के लिए जो वास्तव में तर्क को समझना चाहते हैं, कृपया diveintopython पर 3 पृष्ठों पर एक चरण के स्पष्टीकरण पर एक नज़र डालें

मूल समाधान से एकमात्र अंतर (जो था M{0,4}) क्योंकि मैंने पाया है कि 'MMMM' एक वैध रोमन अंक नहीं है (पुराने रोमनों ने भी शायद उस विशाल संख्या के बारे में नहीं सोचा है और मुझसे असहमत होंगे)। यदि आप पुराने रोमियों को असहमत करने वालों में से एक हैं, तो कृपया मुझे क्षमा करें और {0,4} संस्करण का उपयोग करें।


1
जवाब में regex खाली अंकों की अनुमति देता है। यदि आप इसे नहीं चाहते हैं; आप खाली तारों को अस्वीकार करने के लिए एक लुकहेड जोर का उपयोग कर सकते हैं (यह अक्षरों के मामले को भी अनदेखा करता है)।
20

2

Im इस सवाल का जवाब रोमन अंकों के लिए अजगर में नियमित अभिव्यक्ति है
क्योंकि यह इस सवाल का एक सटीक डुप्लिकेट के रूप में चिह्नित किया गया था।

यह नाम में समान हो सकता है, लेकिन यह एक विशिष्ट रेगेक्स प्रश्न / समस्या है,
जैसा कि उस प्रश्न के उत्तर द्वारा देखा जा सकता है।

मांगी जा रही वस्तुओं को एक एकल प्रत्यावर्तन में जोड़ा जा सकता है और फिर
एक कैप्चर समूह के अंदर संलग्न किया जाता है जिसे खोजक ()
फ़ंक्शन के साथ एक सूची में डाला जाएगा ।
यह इस तरह किया जाता है:

>>> import re
>>> target = (
... r"this should pass v" + "\n"
... r"this is a test iii" + "\n"
... )
>>>
>>> re.findall( r"(?m)\s(i{1,3}v*|v)$", target )
['v', 'iii']

कारक के लिए रेगेक्स संशोधन और सिर्फ अंक पर कब्जा है:

 (?m)
 \s 
 (                     # (1 start)
      i{1,3} 
      v* 
   |  v
 )                     # (1 end)
 $

1

जैसा कि जेरेमी और पैक्स ने ऊपर बताया ... '^ M {0,4} (CM | CD | D | C {0,3}) (XC। XL | L | X {0,3}) (IX | IV) | V! I {0,3}) $ 'समाधान आपके द्वारा किए जाने के बाद होना चाहिए ...

विशिष्ट URL जो संलग्न होना चाहिए था (IMHO) http://thehazeltree.org/diveintopython/7.html

उदाहरण 7.8 {n, m} का उपयोग करते हुए संक्षिप्त रूप है


1

मेरे मामले में, मैं पाठ के अंदर एक शब्द से रोमन संख्याओं की सभी घटनाओं को खोजने और बदलने की कोशिश कर रहा था, इसलिए मैं लाइनों की शुरुआत और अंत का उपयोग नहीं कर सका। तो @paxdiablo समाधान में कई शून्य-लंबाई वाले मैच पाए गए। मैं निम्नलिखित अभिव्यक्ति के साथ समाप्त हुआ:

(?=\b[MCDXLVI]{1,6}\b)M{0,4}(?:CM|CD|D?C{0,3})(?:XC|XL|L?X{0,3})(?:IX|IV|V?I{0,3})

मेरा अंतिम पायथन कोड इस तरह था:

import re
text = "RULES OF LIFE: I. STAY CURIOUS; II. NEVER STOP LEARNING"
text = re.sub(r'(?=\b[MCDXLVI]{1,6}\b)M{0,4}(?:CM|CD|D?C{0,3})(?:XC|XL|L?X{0,3})(?:IX|IV|V?I{0,3})', 'ROMAN', text)
print(text)

आउटपुट:

RULES OF LIFE: ROMAN. STAY CURIOUS; ROMAN. NEVER STOP LEARNING

0

स्टीवन लेविथान अपने पोस्ट में इस रेगेक्स का उपयोग करते हैं जो मूल्य को "व्युत्पन्न" करने से पहले रोमन अंकों को मान्य करता है:

/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/

0

मैंने कई उत्तर देखे हैं जो इसे हल करने के लिए खाली तारों को कवर नहीं करते हैं या लुकहेड्स का उपयोग करते हैं। और मैं एक नया उत्तर जोड़ना चाहता हूं जो खाली तारों को कवर करता है और लुकहेड का उपयोग नहीं करता है। रेगेक्स निम्नलिखित है:

^(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}))$

मैं अनंत के लिए अनुमति दे रहा हूं M, M+लेकिन निश्चित रूप से किसी को M{1,4}केवल 1 या 4 की अनुमति देने के लिए बदल सकता है ।

नीचे एक विज़ुअलाइज़ेशन है जो यह समझने में मदद करता है कि यह क्या कर रहा है, दो ऑनलाइन डेमो से पहले:

डीबगेजक्स डेमो

रेगेक्स 101 डेमो

नियमित अभिव्यक्ति दृश्य


0

यह जावा और पीसीआरई रेगेक्स इंजन में काम करता है और अब इसे नवीनतम जावास्क्रिप्ट में काम करना चाहिए लेकिन सभी संदर्भों में काम नहीं कर सकता है।

(?<![A-Z])(M*(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3}))(?![A-Z])

पहला हिस्सा अत्याचारी नकारात्मक दिखावट है। लेकिन, तार्किक उद्देश्यों के लिए यह समझना सबसे आसान है। मूल रूप से, पहला (?<!)कह रहा है कि बीच से मेल नहीं खाता है ([MATCH])अगर बीच से पहले आने वाले अक्षर हैं ([MATCH])और अंतिम (?!)कह रहा है कि ([MATCH])अगर बीच में पत्र नहीं आते हैं तो बीच से मेल न करें ।

([MATCH])रोमन अंकों के अनुक्रम के मिलान के लिए मध्य केवल सबसे अधिक इस्तेमाल किया जाने वाला रेगेक्स है। लेकिन अब, आप मिलान नहीं करना चाहते हैं कि क्या इसके आसपास कोई पत्र हैं।

अपने आप को देखो। https://regexr.com/4vce5


-1

जेरेमी और पैक्स से समाधान की समस्या यह है कि यह "कुछ भी नहीं" से मेल खाता है।

निम्नलिखित रेगेक्स कम से कम एक रोमन अंक की उम्मीद करता है:

^(M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})|[IDCXMLV])$

6
वह काम नहीं करेगा (जब तक कि आप बहुत अजीब रेगेक्स कार्यान्वयन का उपयोग नहीं कर रहे हैं) - कैन का बायां हिस्सा |खाली स्ट्रिंग और सभी वैध रोमन अंकों से मेल खा सकता है, इसलिए दाईं ओर पूरी तरह से बेमानी है। और हाँ, यह अभी भी एक खाली स्ट्रिंग से मेल खाता है।
23:40 बजे डर्टी आईसीई

"जेरेमी और पैक्स से समाधान की समस्या है" ... ठीक यही समस्या इस उत्तर की है। यदि आप किसी समस्या का समाधान प्रस्तावित करने जा रहे हैं, तो आपको शायद इसका परीक्षण करना चाहिए। :-)
पाक्सिडाब्लो

मुझे इसके साथ खाली स्ट्रिंग मिली
अमीना नूरैनी

-2

मैं मेरे लिए अपने काम के लिए कार्य लिखूंगा। यहां PowerShell में दो रोमन अंक कार्य हैं।

function ConvertFrom-RomanNumeral
{
  <#
    .SYNOPSIS
        Converts a Roman numeral to a number.
    .DESCRIPTION
        Converts a Roman numeral - in the range of I..MMMCMXCIX - to a number.
    .EXAMPLE
        ConvertFrom-RomanNumeral -Numeral MMXIV
    .EXAMPLE
        "MMXIV" | ConvertFrom-RomanNumeral
  #>
    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        [Parameter(Mandatory=$true,
                   HelpMessage="Enter a roman numeral in the range I..MMMCMXCIX",
                   ValueFromPipeline=$true,
                   Position=0)]
        [ValidatePattern("^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$")]
        [string]
        $Numeral
    )

    Begin
    {
        $RomanToDecimal = [ordered]@{
            M  = 1000
            CM =  900
            D  =  500
            CD =  400
            C  =  100
            XC =   90
            L  =   50
            X  =   10
            IX =    9
            V  =    5
            IV =    4
            I  =    1
        }
    }
    Process
    {
        $roman = $Numeral + " "
        $value = 0

        do
        {
            foreach ($key in $RomanToDecimal.Keys)
            {
                if ($key.Length -eq 1)
                {
                    if ($key -match $roman.Substring(0,1))
                    {
                        $value += $RomanToDecimal.$key
                        $roman  = $roman.Substring(1)
                        break
                    }
                }
                else
                {
                    if ($key -match $roman.Substring(0,2))
                    {
                        $value += $RomanToDecimal.$key
                        $roman  = $roman.Substring(2)
                        break
                    }
                }
            }
        }
        until ($roman -eq " ")

        $value
    }
    End
    {
    }
}

function ConvertTo-RomanNumeral
{
  <#
    .SYNOPSIS
        Converts a number to a Roman numeral.
    .DESCRIPTION
        Converts a number - in the range of 1 to 3,999 - to a Roman numeral.
    .EXAMPLE
        ConvertTo-RomanNumeral -Number (Get-Date).Year
    .EXAMPLE
        (Get-Date).Year | ConvertTo-RomanNumeral
  #>
    [CmdletBinding()]
    [OutputType([string])]
    Param
    (
        [Parameter(Mandatory=$true,
                   HelpMessage="Enter an integer in the range 1 to 3,999",
                   ValueFromPipeline=$true,
                   Position=0)]
        [ValidateRange(1,3999)]
        [int]
        $Number
    )

    Begin
    {
        $DecimalToRoman = @{
            Ones      = "","I","II","III","IV","V","VI","VII","VIII","IX";
            Tens      = "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC";
            Hundreds  = "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM";
            Thousands = "","M","MM","MMM"
        }

        $column = @{Thousands = 0; Hundreds = 1; Tens = 2; Ones = 3}
    }
    Process
    {
        [int[]]$digits = $Number.ToString().PadLeft(4,"0").ToCharArray() |
                            ForEach-Object { [Char]::GetNumericValue($_) }

        $RomanNumeral  = ""
        $RomanNumeral += $DecimalToRoman.Thousands[$digits[$column.Thousands]]
        $RomanNumeral += $DecimalToRoman.Hundreds[$digits[$column.Hundreds]]
        $RomanNumeral += $DecimalToRoman.Tens[$digits[$column.Tens]]
        $RomanNumeral += $DecimalToRoman.Ones[$digits[$column.Ones]]

        $RomanNumeral
    }
    End
    {
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.