将分数替换为分数正则表达式,将数字替换为数字正则表达式

Replace fractions with fractions regular expressions, numbers with numbers regular expression

本文关键字:正则表达式 数字 替换      更新时间:2023-09-26

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

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

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

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);
    });
}

不幸的是,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]);
        }   
    }
}

我认为这种方法为你想做的事情提供了最大的灵活性。对于每一行,你会得到一个所有分数的数组和一个所有数字的数组。您可以放置布尔值来检查行是否同时包含数字和分数,或者只有一个或另一个。如果需要进行计算,可以根据每行的分数和数字数组创建公式。

计算

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");

我认为这种方法可以满足您的需要。只要调用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}