Skip to content

Instantly share code, notes, and snippets.

@khornberg
Created August 5, 2013 19:03
Show Gist options
  • Save khornberg/6158495 to your computer and use it in GitHub Desktop.
Save khornberg/6158495 to your computer and use it in GitHub Desktop.
Converts roman numerals to arabic numerals and arabic numerals to roman numerals. Replaces roman numerals with arabic numerals.
/**
* Converts roman numerals to arabic numerals and arabic numerals to roman numerals.
* @author Daniel Wachsstock
* @internal Modified by khornberg
* @license MIT
* @link from http://bililite.com/blog/2009/03/09/roman-numerals-in-javascript/ Daniel's orginal post
*
*/
var romanNumerals = [
[1000, 'M'],
[900, 'CM'],
[500, 'D'],
[400, 'CD'],
[100, 'C'],
[90, 'XC'],
[50, 'L'],
[40, 'XL'],
[10, 'X'],
[9, 'IX'],
[5, 'V'],
[4, 'IV'],
[1, 'I']
];
/**
* Converts arabic numeral to roman numeral
* @method arabic2roman
* @param {integer} arabic numeral
* @return {string} roman numeral
*/
arabic2roman = function(n){
var r = '';
for (var i = 0; i < romanNumerals.length; ++i){
for (var x = romanNumerals[i]; n >= x[0]; n -= x[0]) r += x[1];
}
return r;
}
/**
* Converts roman numeral to arabic numeral
* @method roman2arabic
* @param {string} roman numeral
* @return {integer} arabic numeral
*/
roman2arabic = function(r){
// Test if string is a valid roman numeral
var rom = '^((CM|CD)|(D)?(C){0,3})((XC|XL)|(L)?(X){0,3})((IX|IV)|(V)?(I){0,3})$';
var romanRegExp = new RegExp(rom ,'mi');
if(romanRegExp.test(r)) {
var n = 0;
for (var i = 0; i < romanNumerals.length; ++i){
for (var x = romanNumerals[i], l = x[1].length; r.substr(0,l).toUpperCase() == x[1]; r = r.substr(l).toUpperCase())
n += x[0];
}
return n;
}
else {
return r;
}
}
/**
* Replaces roman numerals with arabic numerals
* @method replaceRoman
* @param {string} String with roman numerals
* @return {string} String with roman numerals replaced with arabic numerals
*/
replaceRoman = function(str) {
// get roman numerals from string
var matches = str.match(/((CM|CD)|(D)?(C){0,3})((XC|XL)|(L)?(X){0,3})((IX|IV)|(V)?(I){0,3})(?=(\s|[\.,;:-])|$)/gi);
// remove "", null, undefined, and 0
matches = matches.filter(function(e){return e});
// replace the roman numerals with arabic numerals
for (var i = matches.length - 1; i >= 0; i--) {
var arabicNumeral = roman2arabic(matches[i]);
var romanNumeral = new RegExp('\\b' + matches[i] + '(?=(\\s|[\.,;:-])|$)', 'gi');
var str = str.replace(romanNumeral, arabicNumeral);
}
return str;
}
// Tests
var testRoman = ['MCMXC', 'MDCLXIV', 'MMVIII', 'cxii', 'xcv', 'iix', 'xi', 'iii', 'iota', 'I\'m', 'Verily'];
var testArab = [2, 150, 2014, 48, 87];
var testReplace = [
'Chapter. verse before John i. 10 after',
'Chapter before 1Pe i. after',
'Chapter II Cor. v:18–20',
'Chapter.verse–verse before Jude vi; i John xii; iii JOhn xiii-xiv after',
'Chapter.verse–verse before John xii-xiii after',
'Chapter:verse;chapter:verse before John i:10-11, xii:12-24; v:20 after',
'Chapter before Gen i after',
'Chapter.verse–verse Mar 15; Jul 10, 2010; Jan 15, 1989',
'Chapter:verse;chapter:verse before John i:10, 12; v:20 after',
'Chapter before John i after',
'Chapter. before John i. after',
'Chapter, before John i, after',
'Chapter:verse before John i:10 after',
'Chapter:verse-verse before John i:10-12 after',
'Chapter:verse,verse before John i:10, 20 after',
'Chapter:verse-verse before Johni1:10-12 after',
'Chapter:verse–verse before John i:10–20 after',
'Chapter.verse–verse before John i.10–20 after',
'Chapter. verse before Psalm i. 1 after',
'Chapter. verse before Psalm ii. 1 after',
'Chapter. verse before Psalm iii. 1 after',
'Chapter. verse before Psalm iv. 1 after',
'Chapter. verse before Psalm v. 1 after',
'Chapter. verse before Psalm xlvi. 1 after',
'Chapter. verse before Psalm lvii. 1 after',
'Chapter. verse before Psalm viii. 1 after',
'Chapter. verse before Psalm xcix. 1 after',
'Chapter. verse before Psalm x. 1 after',
'Chapter. verse before Psalm cxi. 1 after',
];
var testReplaceCorrectResults = [
'Chapter. verse before John 1. 10 after',
'Chapter before 1Pe 1. after',
'Chapter 2 Cor. 5:18–20',
'Chapter.verse–verse before Jude 6; 1 John 12; 3 JOhn 13-14 after',
'Chapter.verse–verse before John 12-13 after',
'Chapter:verse;chapter:verse before John 1:10-11, 12:12-24; 5:20 after',
'Chapter before Gen 1 after',
'Chapter.verse–verse Mar 15; Jul 10, 2010; Jan 15, 1989',
'Chapter:verse;chapter:verse before John 1:10, 12; 5:20 after',
'Chapter before John 1 after',
'Chapter. before John 1. after',
'Chapter, before John 1, after',
'Chapter:verse before John 1:10 after',
'Chapter:verse-verse before John 1:10-12 after',
'Chapter:verse,verse before John 1:10, 20 after',
'Chapter:verse-verse before Johni1:10-12 after',
'Chapter:verse–verse before John 1:10–20 after',
'Chapter.verse–verse before John 1.10–20 after',
'Chapter. verse before Psalm 1. 1 after',
'Chapter. verse before Psalm 2. 1 after',
'Chapter. verse before Psalm 3. 1 after',
'Chapter. verse before Psalm 4. 1 after',
'Chapter. verse before Psalm 5. 1 after',
'Chapter. verse before Psalm 46. 1 after',
'Chapter. verse before Psalm 57. 1 after',
'Chapter. verse before Psalm 8. 1 after',
'Chapter. verse before Psalm 99. 1 after',
'Chapter. verse before Psalm 10. 1 after',
'Chapter. verse before Psalm 111. 1 after',
];
var i = 0;
for (; i<testRoman.length; i++) {
console.log(testRoman[i] + ": " + roman2arabic(testRoman[i] );
}
for (; i<testArab.length; i++) {
console.log(testArab[i] + ": " + arabic2roman(testArab[i]));
}
var match = false;
for (; i<testReplace.length; i++) {
console.log("Test: " + testReplace[i] + "\nResu: " + replaceRoman(testReplace[i]) + "\nShou: " + testReplaceCorrectResults[i]);
match = (replaceRoman(testReplace[i]) == testReplaceCorrectResults[i]) ? true : false;
console.log(match);
}
//sdg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment