Rod
Rod

Reputation: 15457

regex to grab 2 strings from line

is this the correct way to handle this?

string item = "strawb bana  .93";

string itemPattern = @"\w*";
string pricePattern = @"\d*\.\d*";

var match = Regex.Match(item, itemPattern, RegexOptions.IgnoreCase);
var match2 = Regex.Match(item, pricePattern, RegexOptions.IgnoreCase);

if (match.Success & match2.Success)
{
    Console.WriteLine("match");
    Console.WriteLine(match.Value);
    Console.WriteLine(match2.Value);
}
else
    Console.WriteLine("no match");

is there a more concise way perhaps? Actually, I'm not grabbing the item correctly. Basically, I want to grab the item and price.

Upvotes: 0

Views: 152

Answers (4)

Cfreak
Cfreak

Reputation: 19309

You likely want to combine to one regex and use grouping to capture the parts you want (check my C# as I'm not a C# developer!)

string item = "strawb bana .93";
string pattern = @"([a-z\s]+)(\d*\.\d{2})"
var match = Regex.Match(item,pattern,RegexOptions.IgnoreCase);

if( match.Success ) {
    item_name = match.Groups[1].value;
    price = match.Groups[2].value;
}

As for the regex itself:

([a-z\s]+) matches one or more (the + sign) letters or spaces and captures them as group 1

(\d*\. starts group two and optionally matches one or more numbers followed by a period

\d{2}) matches exactly two digits and closes the second group

Edit: There seems to be some disagreement about how ? is interpreted by C#. I've changed \d+? to \d* which means "0 or more digits"

Upvotes: 0

Ria
Ria

Reputation: 10347

Try this regex:

[\w\s]*\d*\.\d*

and by using Grouping constructs, your code should be like this:

string item = "strawb bana  .93";

foreach(Match match in Regex.Matches(item, @"(?<str>[\w\s]*)(?<num>\d*\.\d+)"))
{
    String str = match.Groups["str"].Value;
    String nuum = match.Groups["num"].Value;
}

explain:

(?< name > subexpression) Captures the matched subexpression into a named group.

Upvotes: -1

Scott Weaver
Scott Weaver

Reputation: 7361

([a-zA-Z\s]+).*?(\d*\.\d{2})  //item in group 1, price in group 2

*case insensitive, matches prices of .93 or 11.93 (digits preceding decimals are optional), also will match a slighter weirder string like "Strawb bana-11.98"

updated: to match items with numbers in them:

([\w\s]+?).?(\d*\.\d{2}) //matches 'item42 Bananas .55'

(clearly you can keep dreaming up inputs and making the pattern progressively more complicated, but maybe I should just go to bed :)

Upvotes: 1

Shiridish
Shiridish

Reputation: 4962

Just change the line to this and it should match your item even if it contains spaces:

string itemPattern = @"[a-z\s]*";

UPDATE: A better approach is to use groups:

        string item = "strawb bana as .93";
        string itemPattern = @"([a-z\s]*)(\d*\.*\d*)";
        var match = Regex.Match(item, itemPattern, RegexOptions.IgnoreCase);
        if (match.Success)
        {
            Console.WriteLine("match");
            Console.WriteLine("name: "+match.Groups[1].Value);
            Console.WriteLine("Price: "+match.Groups[2].Value);
        }
        else
            Console.WriteLine("no match");
        Console.Read();

Upvotes: 1

Related Questions