Home > Mobile >  Regex for roman numeral to integer
Regex for roman numeral to integer

Time:09-18

This regex is meant for matching ocurrences listed in next table. Then I will turn every match into it's corresponding integer value

const regex = /[I,V,X,L,C,D,M,IV,IX,XL,XC,CD,CM]/g
Roman numeral Integer value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
IV 4
IX 9
XL 40
XC 90
CD 400
CM 900

For this particular string example I want the code snippet to match only ['XC'] however it's actually returning ['X','C'] separately.

const regex = /[I,V,X,L,C,D,M,IV,IX,XL,XC,CD,CM]/g
const test = 'XC'
console.log(test.match(regex))

Is it possible to achive this by using regex?

CodePudding user response:

You have RegExp:

const regex = /[I,V,X,L,C,D,M,IV,IX,XL,XC,CD,CM]/g

and string XC, in which you do matching. RegExp is going through your string and matches each symbol in [...], because grouping in RegExp is done by (..|..|..), so first it finds X in XC, then C.

You can change your program logic a bit and create roman-arabic number object from your table. After this you'll have easy access to roman-arabic dictionary. Check inline comments:

// Create roman number object
const romNumObj = {
  I: 1, V: 5, X: 10, L: 50, C: 100,
  D: 500, M: 1000, IV: 4, IX: 9,
  XL: 40, XC: 90, CD: 400, CM: 900
};

// Find romNum function
const romNum = code => romNumObj[code] ? romNumObj[code] : false;

// Test
console.log(`XC: ${romNum('XC')}`);
console.log(`I I: ${romNum('I')   romNum('I')}`);
console.log(`DC: ${romNum('DC')}`);

CodePudding user response:

Logically you want to select the X that doesn't come before a C witch can be done with this regex:

/(X^C)|XC/g

It looks ugly because you have to do it for all other letters, but this is exactly what you want.

const regex = /(X^C)|XC/g
const test = 'XC'
console.log(test.match(regex))

btw you can add as mutch as you want using this : (I^V)|IV|(I^X)|IX


I made this code that generates your regex for you
var letters = ['I','V','X','L','C','D','M','IV','IX','XL','XC','CD','CM'];
//make sure letters has unique items !!!
//and sorted by length !!!

var yourRegEx = '';
for(var i=0 ; i < letters.length - 1 ; i  ){
  var alreadyDone = false;
  for(var j=(i 1) ; j < letters.length ; j  ){
    if(letters[j].includes(letters[i])){
      alreadyDone = true;
      yourRegEx  = '|('   letters[i] '^' letters[j].replace(letters[i],'')   ')';
    }
    
  }
  if(!alreadyDone){
    yourRegEx  = '|'   letters[i];
  }
  
}
yourRegEx =  yourRegEx.substring(1)   '|'   letters[letters.length-1];


// here is Your regex
console.log(yourRegEx);
  • Related