用分数正则表达式替换分数,用数字正则表达式代替数字

时间:2012-02-29 18:23:13

标签: javascript regex

我想在示例输入上运行以下正则表达式,以替换数字和分数(我需要将它们乘以用户将选择的数字):

numbersRegex = /[0-9]+(?:\.[0-9]*)?/g;
fractionsRegex = /((\d+)\/(\d+))/g;

numbersRegex需要在仅包含数字的行上运行(我使用numbersRegex在下面的示例输入中标记它们。)

fractionsRegex只需要在包含分数的行上运行(我使用fractionsRegex在下面的示例输入中标记它们)。

我需要它们是两个不同的,因为乘法方法不同,所以我想运行str.replace两次,一个乘以所有分数,另一个乘以所有数字。

以下是示例输入:

1 1/2 oz. white rum (fractionsRegex)
1/2 lime, cut in 4 wedges (fractionsRegex)
10 mint leaves, fresh (numbersRegex)
2 tbsp. white sugar (numbersRegex)
1 cup ice cubes (numbersRegex)
1/2 cup club soda (fractionsRegex)

这可能吗?

非常感谢

更新

这是我目前正在使用的功能(需要清理它,我确信它也可以进行优化):

function _increaseServings(target, initialServings, newServings) {
    target.html(originalIngredientsHTML);

    target.find('li').each(function(i) {
        var currentLine = $(this).text();
        var importantPart = currentLine.split(',');

        var fractionsRegex = importantPart[0].match(/((\d+)\/(\d+))/g);
        var lineHiddenFractions = importantPart[0] != null ? importantPart[0].replace(/([0-9]{1,})([\/]{1})([0-9]{1,})/g, "") : "";
        var numbersRegex = lineHiddenFractions.match(/([0-9]+(?:\.[0-9]*)?)/g);

        var result = {};
        var strToReplace = '';

        if (fractionsRegex == null && numbersRegex == null) return;

        if (fractionsRegex !== null && fractionsRegex.length > 0) {
            result.fraction = fractionsRegex[0];

            strToReplace = result.fraction;
        }

        if (numbersRegex !== null && numbersRegex.length > 0) {
            result.number = parseInt(numbersRegex[0]);

            if(result.fraction) {
                strToReplace = result.number + ' ' + strToReplace;
            } else {
                strToReplace = result.number;
            }   
        }

        if(result.fraction) {
            var fraction = result.fraction.split('/');
            if(result.number && result.fraction) {
                result.decimal = parseInt(result.number) + parseInt(fraction[0]) / parseInt(fraction[1]);
            } else {
                result.decimal = parseInt(fraction[0]) / parseInt(fraction[1]);                
            }
        } else {
            result.decimal = parseInt(result.number);
        }

        result.stringToReplace = strToReplace;

        var newValue = result.decimal * (newServings / initialServings);

        if(newValue % 1 != 0) {
            var values = String(newValue).split('.');

            var checkValue = String(values[1]).slice(0,1);
            var integerPart = Math.floor(newValue);

            if(checkValue == 2) {
                // 25
                newValue = integerPart + ' 1/4';
            } else if(checkValue == 3) {
                // 33
                newValue = integerPart + ' 1/3';
            } else if(checkValue == 5) {
                // 50
                newValue = integerPart + ' 1/2';
            } else if(checkValue == 6) {
                // 66
                newValue = integerPart + ' 2/3';
            } else if(checkValue == 7) {
                // 75
                newValue = integerPart + ' 3/4';
            }

            if(integerPart == 0) newValue = newValue.slice(2, newValue.length);
        }

        currentLine = currentLine.replace(strToReplace, newValue);

        $(this).text(currentLine);
    });
}

3 个答案:

答案 0 :(得分:1)

计算

function measure(string){
  var match = string.match(/^\d+(\s*\d*(\/+\d+))*/);
  if(match){
     match = match[0].split(" ");
     var m = 0;
     while(match.length){
        m += eval(match.shift());
     }
     return m;
  }
  return 0;
}

或单独获取值

function get(string){
  var match = string.match(/^\d+(\s*\d*(\/+\d+))*/);
  if(match){
     match = match[0].split(" ");
     var m = 0;
     while(match.length){
        m += eval(match.shift());
     }
     return {integer:Math.floor(m), fraction:m-Math.floor(m)};
  }
  return {integer:0, fraction:0};
}

或单独替换整数部分和分数部分

function replaceInteger(string, newInt){
  return string.replace(/^\d+\s+/, function(m, n){
     return newInt + " ";
  });
}

function replaceFraction(string, newFract){
  return string.replace(/^\d+\/+\d+\s+/, function(m, n){
     return newFract + " ";
  });
}

replaceInteger("10 mint leaves, fresh", "100");
replaceFraction("1/2 lime leaves, fresh", "1/3");

答案 1 :(得分:1)

不幸的是,javascript正则表达式不支持负面的lookbehinds,因此当你寻找只是数字时,你会得到你的分数的误报。没有办法说出......

"/(?<!\/)([0-9])/"

...在javascript中,所以你最终会从分数中获取一些数字。

您必须使用以下内容伪造结果:

假设您的文本以\ n结尾,仅用于测试目的:

var t = "1 1/2 oz. white rum (fractionsRegex)\n1/2 lime, cut in 4 wedges (fractionsRegex)\n10 mint leaves, fresh (numbersRegex)\n2 tbsp. white sugar (numbersRegex)\n1 cup ice cubes (numbersRegex)\n1/2 cup club soda (fractionsRegex)";
var ary = t.split("\n");

for (var i = 0; i < ary.length; i++) {
    var fractionsRegex = ary[i].match(/((\d+)\/(\d+))/g);
    var lineHiddenFractions = ary[i] != null ? ary[i].replace(/([0-9]{1,})([\/]{1})([0-9]{1,})/g, "") : "";
    var numbersRegex = lineHiddenFractions.match(/([0-9]+(?:\.[0-9]*)?)/g);
    if (fractionsRegex !== null && fractionsRegex.length > 0) {
        // We have a fraction for this line.
        for (var j = 0; j < fractionsRegex.length; j++) {
            alert("Fraction on line " + i + ": " + fractionsRegex[j]);
        }
    }   
    if (numbersRegex !== null && numbersRegex.length > 0) {
        // We have a number for this line.
        for (var k = 0; k < numbersRegex.length; k++) {
            alert("Number on line " + i + ": " + numbersRegex[k]);
        }   
    }
}

我认为这种方法可以为您提供最大的灵活性。对于每一行,您将获得所有分数的数组和所有数字的数组。您可以放置​​布尔值来检查线路是否同时具有数字和分数,或者只有一个或两个。如果需要执行计算,可以从每行的分数和数字数组创建公式。

答案 2 :(得分:0)

我认为这种方法可以满足您的需求。只需致电getQuantity,它就会返回一个对象,该对象可能包含也可能不包含属性numberfraction。然后,一旦得到结果,就可以执行逻辑来确定如何处理它。

function getQuantity(recipe){
    var regex = /^(([1-9]+\d*\s)?((\d+)\/(\d+)\s)?).*$/g;
    var results = regex.exec(recipe);
    if(results[2] && results[5]){
         return {number: Number(results[2]), fraction: Number(results[4]) / Number(results[5])};
    } if(results[5]){
         return {fraction: Number(results[4]) / Number(results[5])};
    } else{
         return {number: Number(results[2])};
    }
 }

getQuantity("1 1/2 oz. white rum"); // {number: 1, fraction: 0.5}
getQuantity("1/2 lime, cut in 4 wedges"); // {fraction: 0.5}
getQuantity("10 mint leaves, fresh"); // {number: 10}
getQuantity("2 tbsp. white sugar"); // {number: 2}
getQuantity("1 cup ice cubes"); // {number: 1}
getQuantity("1/2 cup club soda"); // {fraction: 0.5}