How to make a c# regex match only the *last* occurrence of a pattern?

  • Thread starter sherifffruitfly
  • Start date
S

sherifffruitfly

Hi,

I've been searching as best I can for this - coming up with little.

I have a file that is full of lines fitting this pattern:

(?<year>\d{4}),(?<amount>\d{6,7})

I'm likely to get a bunch of hits with this - I'm only interested in
the *last* one. Is there a way to build the concept "last" into the
regex itself? Or is taking the last element of the match array the only
thing to do?

I would just prefer to avoid have a potentially long array being sent
around...

Thanks,

cdj
 
G

Guest

One suggestion is to find the last index of the newline character, and regex
everything after that, if now match, last index it again on everything before
it and they the reg ex on that line. you could keep doing this till a match
occurs. I'm not a regex expert but I dont believe you can specify the last
match.

HTH

Ciaran
 
J

Jeroen

Hi,

You can find what you want by searching for the occurrence of your
pattern that does not have _another_ occurrence of that pattern after
it.

Suppose your pattern is P. You can search for the last P by doing a
search for "anything" followed by "P" followed by "anything but P".

Or you can try google (d'oh, right? :D "pattern matching c# last"):

http://www.google.nl/search?hs=ue5&...&q=pattern+matching+c#+last&btnG=Zoeken&meta=

In short, the solution presented at the first hit from google is to use
the RegexOptions.RightToLeft parameter :p

-Jeroen
 
G

Guest

Like I said, I'm no regex guru so I offered a coding way round it. The regex
option is undoubtedly better.

Ciaran O'Donnell
 
S

sherifffruitfly

Jeroen said:
Hi,

You can find what you want by searching for the occurrence of your
pattern that does not have _another_ occurrence of that pattern after
it.

Suppose your pattern is P. You can search for the last P by doing a
search for "anything" followed by "P" followed by "anything but P".

Or you can try google (d'oh, right? :D "pattern matching c# last"):

Which I did long before I posted the question. I saw the right-to-left
trick. I was simply hoping for a "pure regex solution", rather than an
implementation-specific solution.

I'll see if I can get your first idea to work for me though - thanks a
bunch!

cdj
 
G

Greg Bacon

: I have a file that is full of lines fitting this pattern:
:
: (?<year>\d{4}),(?<amount>\d{6,7})
:
: I'm likely to get a bunch of hits with this - I'm only interested in
: the *last* one. Is there a way to build the concept "last" into the
: regex itself? Or is taking the last element of the match array the only
: thing to do?
:
: I would just prefer to avoid have a potentially long array being sent
: around...

Start your pattern with .* to grab the last match. For example:

using System;
using System.Text.RegularExpressions;

namespace consapp
{
class Program
{
static void Main(string[] args)
{
const string pattern = @"(?<year>\d{4}),(?<amount>\d{6,7})";
Regex regex;
Match m;
string input = "1234,1234569999,123456";

Console.WriteLine("Vanilla pattern:");
regex = new Regex(pattern);
m = regex.Match(input);
Console.WriteLine(" - year=[{0}], amount={1}",
m.Groups["year"], m.Groups["amount"]);

Console.WriteLine("Leading dot-star:");
regex = new Regex(".*" + pattern);
m = regex.Match(input);
Console.WriteLine(" - year=[{0}], amount={1}",
m.Groups["year"], m.Groups["amount"]);
}
}
}

Output:

Vanilla pattern:
- year=[1234], amount=1234569
Leading dot-star:
- year=[9999], amount=123456

Hope this helps,
Greg
 
J

Jon Shemitz

sherifffruitfly said:
Which I did long before I posted the question. I saw the right-to-left
trick. I was simply hoping for a "pure regex solution", rather than an
implementation-specific solution.

I'll see if I can get your first idea to work for me though - thanks a
bunch!

Well, it might have been a good idea to mention this - something like
"I know about the right-to-left flag, but I want a portable solution."

Fwiw, while using .* to skip to the end and work backward should be
pretty fast, it will only let you find the last match. Using the
right-to-left flag will let you quickly find the last N matches.
 
S

sherifffruitfly

Well, it might have been a good idea to mention this - something like
"I know about the right-to-left flag, but I want a portable solution."

Sigh.

You DON'T google before asking, and you get reamed.

You DO google before asking, and still get reamed.


Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top