2012-02-29 254 views
2

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

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

的numbersRegex需要对仅包含数字线运行(I标记他们使用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) 

这可能吗?

非常感谢

UPDATE

这是我目前使用(它需要进行清理,我敢肯定,它也可以被优化)功能:

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

不知道我是否理解你的问题。你想** 1 **正则表达式,将提取分数线的分数和没有分数的线的数量? – 2012-02-29 18:32:34

+0

我真的不明白你的问题。你想确定字符串是否包含一个小数或一个数字来决定你将使用哪一个正则表达式?如果是这样,首先使用分数正则表达式测试字符串是否包含分数。如果测试失败,请使用数字正则表达式。如果这没有帮助,请澄清你的问题。 :) – tleilax 2012-02-29 18:30:03

+0

我编辑了问题来解释更好 – 2012-02-29 18:48:13

回答

1

不幸的是更换整数部分和小数部分,JavaScript的正则表达式不要支持负向后视,所以当你正在寻找数字时,你会得到你的分数的误报。有没有办法这样说......

"/(?<!\/)([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]); 
     } 
    } 
} 

我觉得这个方法为您提供最大的灵活性你想做什么。对于每一行,您将获得所有分数的数组以及所有数字的数组。你可以放置布尔值来检查该行是否有数字和分数,或者只有一个或另一个。如果您需要执行计算,则可以从每行的分数和数字数组中创建公式。

+0

+1我测试了所有建议,并最终使用了这个。我最后的功能需要清理和优化,但它目前正在做我想要的。非常感谢大家 – 2012-03-05 20:57:02

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

或seperately

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