2012-09-14 14 views
5

Lo que estoy tratando de lograr es reemplazar los números en la cadena con un nuevo valor calculado a partir del (match * int).Buscar y reemplazar números en cadena con expresiones regulares

Así que la entrada de cadena se parece a:

500g Flour 
14g Salt 
7g Dry yeast 
45ml Olive oil 
309ml Water 

Y el resultado debería tener este aspecto:

1000g Flour 
28g Salt 
14g Dry yeast 
90ml Olive oil 
618 ml Water 

row["ingredients"] es una DataRow.

Esto es donde estoy:

System.Text.RegularExpressions. 
     Regex.Replace(row["ingredients"].ToString(), 
         @"[^/d]", Delegate(Match match) { return match * 2; }, 
         RegexOptions.Multiline); 

Cualquier solución es muy apreciada.

+3

Posiblemente una pregunta tonta, pero ¿hay alguna razón? ¿por qué no doblas la sal junto con los otros ingredientes? – dash

+0

¿la '500g Harina 14g' debe cambiarse a' 1000g de Harina 28g de sal'? si no, creo que todas las respuestas deben considerarse así. – hamed

+0

Typo, debería haber sido 28 g de sal – James

Respuesta

4

El primer problema es que su expresión regular solo coincide con caracteres que no son un dígito.

Corrección: Está utilizando barras inclinadas en lugar de una barra invertida, por lo que se emparejan cualquier cosa que no es una barra o un anuncio

Cambie su expresión regular para @"\b(\d+)"

es un ejemplo de trabajo en dotnetfiddle.net

Aquí
using System; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var string1 = "500g Flour 14g Salt 7g Dry yeast 45ml Olive oil 309ml Water"; 

      var result = Regex.Replace(string1, @"\b(\d+)", Doubler, RegexOptions.Multiline); 

      Console.WriteLine(result); 

      Console.ReadKey(); 
     } 

     private static string Doubler(Match match) 
     { 
      return (Convert.ToInt32(match.Value)*2).ToString(); 
     } 
    } 
} 
+0

¿Por qué el voto a favor? – CaffGeek

+0

No soy yo, pero tu expresión regular coincide con la cadena literal '/ w /', seguida de una o más 'd's. –

+0

@TimPietzcker, error tipográfico, esos deberían haber sido barras invertidas, fijo – CaffGeek

1

[^/d] significa "cualquier carácter excepto barra o la letra d".

Para que coincida un número, use \d+.

0

Mantener diferentes tipos de datos en datarow no es una buena práctica. En su muestra: "Harina 500g" - aquí tiene ingredientValue, measureType, ingredientName. Recomendaría crear una pequeña clase de datos que represente esta fila, y todo tipo de datos serán propiedades de esta clase.
beneficios son ajenos:
- No se necesita reemplazar con expresiones regulares magia
- Fácil de ampliar y modificar

Todo lo que necesita con expresiones regulares es crear correcta analizador de la fila de datos proporcionado. Pero con seguridad es más fácil que trucos con reemplazar.

0
void Main() 
{ 
    string ingredients = 
@"500g Flour 
0.5g Salt 
7g Dry yeast 
45ml Olive oil 
309ml Water"; 

    string pattern = @"(?:[0-9]+\.?[0-9]*|\.[0-9]+)"; 

    int multiple = 2; 

    Regex.Replace(ingredients, pattern, m => (Convert.ToDecimal(m.Value)*multiple).ToString()).Dump(); 
} 

Hice esto en LINQPad así que no se preocupe por el volcado() que es solo para dar salida al resultado. Y cambié la sal a 0.5 solo para mostrar que funciona con números enteros. Ese patrón es lo mejor que pude encontrar para hacer coincidir enteros y decimales (con o sin cualquier número antes del decimal) para que coincida con 17, 3.141592 o .5

Cuestiones relacionadas