10

Is there an equivalent of java.util.regex.Matcher.hitEnd() in C# Regex?

Javadoc for boolean hitEnd():

Returns true if the end of input was hit by the search engine in the last match operation performed by this matcher. When this method returns true, then it is possible that more input would have changed the result of the last search.

@return true iff the end of input was hit in the last match; false otherwise

More reference to hitEnd

Community
  • 1
  • 1
mgukov
  • 493
  • 5
  • 18

3 Answers3

2

To know if the end has been reached -

I submit that it is as easy as adding (\z)? at the end of your regex,
or anyplace in your regex where you think could match to the end.

This is a passive check you can do, and it will not interfere with any of
the other constructs in any way.

Here is a C# sample usage:

var str =
    "Foo $var1 <br/>Yes\n" +
    "......... <br/>\n" +
    "......... <br/><br/>\n" +
    "Foo $var2 <br/>Yes\n" +
    "..........<br/>\n" +
    "Yes..........<br/>\n" +
    "..........<br/>\n" +
    "YesYes";

var rx = new Regex(@"Yes(\z)?");

Match M = rx.Match(str);
while (M.Success)
{
    bool bAtEnd = M.Groups[1].Success;
    Console.WriteLine("Match = {0} , At end  {1}", M.ToString(), bAtEnd);
    M = M.NextMatch();
}

Output:

Match = Yes , At end  False
Match = Yes , At end  False
Match = Yes , At end  False
Match = Yes , At end  False
Match = Yes , At end  True
0

No.

But it is not hard to build it yourself.

If using Regex.Match(…) (ie. match the expression once) then:

bool hitEnd = match.Success && input.Length == (match.Index + match.Length)

If using Regex.Matches(…) returning a MatchCollection the last successful match is needed (with a little Enumerable help) and can easily be an extension method:

static bool HitEnd(this MatchCollection matches, string input) {
  if (matches.Count == 0) {
    return false; // No matches at all
  }
  var lastMatch = matches.Cast<Match>().Last();
  return input.Length == (lastMatch.Index + lastMatch.Length)
}
Richard
  • 106,783
  • 21
  • 203
  • 265
  • 1
    It's not that. You are wrong. Java `hitEnd`, for example, : `regex = "[0-9]abc"; input = "1ab"`. Does not match, but hitEnd is true. – mgukov Sep 25 '13 at 12:40
  • @Michael If you are interested in this fail case... that's more difficult to work out if it is possible (and that's a big if). – Richard Sep 25 '13 at 16:24
0

Built-in .NET alternative

It seems there is no direct built-in .NET alternative (within the System.Text.RegularExpressions namespace) to the Java java.util.regex.Matcher.hitEnd() method.

Alternative libraries

Probably, an alternative library could be found that provides the required alternative.

PCRE.NET

For example, a quick search revealed the library: ltrzesniewski/pcre-net: PCRE.NET - Perl Compatible Regular Expressions for .NET. As per its documentation (README.md), the library supports the partial matching:

Example usage

<…>

  • Partial matching:

    var regex = new PcreRegex(@"(?<=abc)123");
    var match = regex.Match("xyzabc12", PcreMatchOptions.PartialSoft);
    // result: match.IsPartialMatch == true
    
  • And a partial match means the same as hit the end ? Really, what has this to do with is this the end. Obviously, you don't need a library to find this out . –  Sep 15 '19 at 20:50
  • @sln, quoting [ltrzesniewski/pcre-net: PCRE.NET - Perl Compatible Regular Expressions for .NET](https://github.com/ltrzesniewski/pcre-net): «Partial matching (when the subject is too short to match the pattern)». As I understand, it means that the end of the subject (the input string) has been hit. – Sergey Vyacheslavovich Brunov Sep 15 '19 at 22:03
  • Begin to wonder if you need an additional library to compare the match position plus length to the target length, you know what I mean ? I mean, there is no magic in Regular Expressions, absolutely none, no elixers, it's all hooey and snaked oil my man !! A bunch of bogosity and bolognies .. –  Sep 15 '19 at 22:31