+3  A: 

Use this pattern: \d+(,\d+)?.

  • \d: matches digits from 0-9
  • +: matches the pattern at least once, so \d+ will match at least one digit
  • (,\d+)?: this indicates a group (using the parentheses) that matches the comma followed by digits and optionally matches it (due to the ? at the end of the group)

Code snippet:

string[] inputs = { "82&?", "82,9", "abse82,9>dpkg", "foobar" };
foreach (var input in inputs)
{
    Match m = Regex.Match(input, @"\d+(,\d+)?");
    if (m.Success)
    {
        Console.WriteLine(m.Value);
    }
    else
    {
        Console.WriteLine("No match!");
    }
}
Ahmad Mageed
+1  A: 

If you are only looking for those characters and trying to rip out anything else you can do the following

    var strings = new List<string>()
                    {
                        "82&?",
                        "82,9",
                        "abse82,9>dpkg"
                    };
    var reg = new Regex("[^0-9,]*", RegexOptions.None);
    var output = new List<string>();
    foreach(var str in strings)
    {
        output.Add(reg.Replace(str, ""));
    }
JoshVarga
+3  A: 

If you are on .NET3.5+ you can use LINQ. A solution without Regex (which is faster) is the following:

var strings = new List<string>() { "82&?", "82,9", "abse82,9>dpkg" };
var result = strings.Select(s =>
    String.Join("",
        s.Where(c => char.IsNumber(c) || c == ',')
        .ToArray()) /* .ToArray() is not needed on .NET 4 */
    ).ToList();

It only select characters that are numbers or comma. But given the string 8,1aa1 it would return 8,11.

This other method is a bit slower, but it will take 8,1 from 8,1aa1 and will not take 8,a or a,a:

var strings = new List<string>() { "82&?887..2", "82,9", "abse82,9>dpkg" };
var result = strings.Select(s =>
    String.Join("",
        s.SkipWhile(c => !char.IsNumber(c))
        .TakeWhile(c => (char.IsNumber(c) || c == ','))
        .ToArray()
    )
).Where(s => char.IsNumber(s.LastOrDefault())).ToList();

Running a test (using Stopwatch) with 100,000 iterations with the methods presented on the answers I got:

Fn: BrunoLM (Method 1)
Ticks: 524999

Fn: BrunoLM (Method 2)
Ticks: 729460

Fn: Ahmad
Ticks: 1323366

Fn: Josh
Ticks: 3783158

The same test with 1000~ length string:

var strings = new List<string>() { "82&?887..2".PadRight(1000, '2'), "82,9".PadRight(1000, '1'), "abse82,9>dpkg".PadRight(1000, 'f') };

Result:

Fn: Ahmad
Ticks: 11911332

Fn: BrunoLM (Method 2)
Ticks: 28149495

Fn: Josh
Ticks: 213681541

Further reading:

regex regular expression and text size n

BrunoLM
Regex gets quicker when you are searching larger strings, but in my experience if you aren't working with strings over 50 characters don't even think about Regex.
Kirk Broadhurst
Regex being slower doesn't mean it's not a good answer. Try "foo,bar" (with a comma) as an input with your solution or with JoshVarga's solution. Currently both solutions would return a comma. [My solution](http://stackoverflow.com/questions/3937427/eliminate-the-letters-or-marks-out-only-leave-numbers-and-apostrophe/3937549#3937549) doesn't consider it a match. Add logic to handle that case and regex quickly dominates IMHO. Granted the OP didn't say he had such a case so it may not be an issue.
Ahmad Mageed
@Ahmad: Thanks for pointing that, I guess I've fixed with `Method 2`. I didn't say your answer is not good. I'm saying that Regex is slow in some cases. If his text has a lot of characters then your solution is much faster as shown above.
BrunoLM
@Kirk: Thanks for sharing it. I've run a test on 1000~ length string and Ahmad's regex won. :)
BrunoLM
@Bruno: I understand, I just meant to say that speed alone isn't always a clear criteria and it ultimately depends on the data (as you've shown with your benchmarks). BTW I am only speculating on what the OP really wants. Regarding the "foo,bar" example I don't know whether that extends to "8,a". Maybe the OP wants "8" in that case, or they may want it only if a digit occurs after the comma (as you have it). The OP would need to clarify. I didn't mean to make you code something the OP didn't request with my comment!
Ahmad Mageed
@BrunoLM - Every time you want to do a regex search, the regex class must be constructed. From what I've read this is a reasonably expensive operation; the class is fairly complex. However once it has been constructed it is exceptionally quick. If you search on strings in the tens or hundreds of thousands you will see the regex solution is many orders faster
Kirk Broadhurst