James
James

Reputation: 439

Find and replace numbers in string with regex

What I'm trying to achieve is to replace the numbers in the string with a new values calculated from the (match * int).

So the string input looks like:

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

And the result should look like this:

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

row["ingredients"] is a DataRow.

This is where I'm at:

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

Any solution is greatly appreciated.

Upvotes: 5

Views: 10733

Answers (4)

CaffGeek
CaffGeek

Reputation: 22054

The first problem is that your regex is only matching characters that are not a digit.

Correction: It is using forward slashes instead of a backslash, so it's matching anything that is not a slash or a d

Change your regex to @"\b(\d+)"

Here's a working example on dotnetfiddle.net

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

Upvotes: 4

Nick
Nick

Reputation: 4766

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

I did this in LINQPad so don't worry about the Dump() that's just to output the result. And I changed salt to 0.5 just to show that it works with non integers. That pattern is the best I could come up with for matching integers and decimals (with or without any number before the decimal) so it'll match 17, 3.141592, or .5

Upvotes: 0

Mykola Kushnir
Mykola Kushnir

Reputation: 61

Hold different type of data into datarow is not good practice. In your sample: "500g Flour" - here you have ingredientValue, measureType, ingredientName. I would recommend create small data class which will represent this row, and all type of data it will be properties of this class.
Benefits are oblivious:
- No needs to replace with regex magic
- Easy to extend and modify

All what you need with regex is to create correct parser of provided data row. But for sure it's more easy then tricks with replace.

Upvotes: 0

Tim Pietzcker
Tim Pietzcker

Reputation: 336128

[^/d] means "any character except slash or the letter d".

To match a number, use \d+.

Upvotes: 1

Related Questions