How to replace all roman numbers in a string for the arabic equivalent?

I have a list of all Shakespeare sonnets and I'm making a function to search for each sonnet. However, I want to be able to search them using arabic numbers (for example "/sonnet 122". The .txt is formatted this way:

I

This is a sonnet

II

This is a second sonnet

I am using node right now to try to do it, but I've been trying since yesterday to no avail. My last attempts yesterday were using the 'replace' method as such:

'use strict';
//require module roman-numerals, which converts roman to arabic
var toArabic = require('roman-numerals').toArabic;
//require file-handling module
var fs = require('fs');

fs.readFile('sonn.txt', 'utf8', function (err,data) {
    if (err) {
        console.log(err);
    } else {
        var RN = /[A-Z]{2,}/g; 
        var found = data.match(RN); //finds all roman numbers and puts them in an array
        var numArr = [];
        for (var i = 0; i < found.length; i++ ){
            numArr.push(toArabic(found[i])); //puts all arabic numbers in numArr
        }
        for (var e = 0; e < found.length; e++){
            data.replace(found, found.forEach((x, i)=> {
            toArabic(x)
    }
});

Then I tried replacing them with:

data.replace(found, function(s, i){
    return numArr[i];
});

Then I tried with a for loop. I didn't keep that code, but it was something like:

for(var i=0;i<found.length;i++){
    data.replace(found, numArr[i]);
}

The last code replaces each number and then erases the data and replaces the next number as such:

replace(abc, 123) -> 1bc, a2c, ab3

How do I make it iterate each occurrence in the data and keep it? Then saving it to a new txt should be easy.

(Also, my RegExp only finds multiple character roman numbers to avoid replacing lonely I's that could be found at the end of a line.)


You have to write the replaced string back, and you could use a callback for replace()

'use strict';

var toArabic = require('roman-numerals').toArabic;
var fs = require('fs');

fs.readFile('sonn.txt', 'utf8', function (err,data) {
    if (err) {
        console.log(err);
    } else {
        data = data.replace(/[A-Z]{2,}/g, function(x) {
            return toArabic(x);
        });
    }
});

Here are some more regular expressions to match romans


If you use String.prototype.replace , you can use your regular expression and a custom replacement function. You just need to return the value to use as a replacement, which is what toArabic does.

var data = 'InnThis is a sonnetnnIInnThis is a second sonnet';

//========================

var toArabic = (function () {
  var forEach = Array.prototype.forEach;


  /**
   * Converts a roman number to its arabic equivalent.
   *
   * Will throw TypeError on non-string inputs.
   *
   * @param {String} roman
   * @return {Number}
   */
  function toArabic (roman) {
    if (('string' !== typeof roman) && (!(roman instanceof String))) throw new TypeError('toArabic expects a string');

    // Zero is/was a special case. I'll go with Dionysius Exiguus on this one as
    // seen on http://en.wikipedia.org/wiki/Roman_numerals#Zero
    if (/^nulla$/i.test(roman) || !roman.length) return 0;

    // Ultra magical regexp to validate roman numbers!
    roman = roman.toUpperCase().match(/^(M{0,3})(CM|DC{0,3}|CD|C{0,3})(XC|LX{0,3}|XL|X{0,3})(IX|VI{0,3}|IV|I{0,3})$/);
    if (!roman) throw new Error('toArabic expects a valid roman number');
    var arabic = 0;

    // Crunching the thousands...
    arabic += roman[1].length * 1000;

    // Crunching the hundreds...
    if (roman[2] === 'CM') arabic += 900;
    else if (roman[2] === 'CD') arabic += 400;
    else arabic += roman[2].length * 100 + (roman[2][0] === 'D' ? 400 : 0);


    // Crunching the tenths
    if (roman[3] === 'XC') arabic += 90;
    else if (roman[3] === 'XL') arabic += 40;
    else arabic += roman[3].length * 10 + (roman[3][0] === 'L' ? 40 : 0);

    // Crunching the...you see where I'm going, right?
    if (roman[4] === 'IX') arabic += 9;
    else if (roman[4] === 'IV') arabic += 4;
    else arabic += roman[4].length * 1 + (roman[4][0] === 'V' ? 4 : 0);
    return arabic;
  };
  return toArabic;
})();

//====================

var RN = /[A-Z]{1,2}(?=n)/g;
var newData = data.replace(RN, toArabic);
document.body.innerText = newData;

链接地址: http://www.djcxy.com/p/37234.html

上一篇: 自由物体是如何构建的?

下一篇: 如何替换阿拉伯语等价字符串中的所有罗马数字?