2

I'm writing a quick utility program in C# to modify all of my Visual Studio C# item templates to add extra using ; statements. I've written a simple regular-expression to (hackishly) extract the set of current namespaces imports in each file so I can add my desired new imports without duplication.

I'm using Regex101.com to test my regular-expressions before inserting them into my C# program, but when I tested them in my C# program they didn't work. This confuses me because the regex itself is trivial, it uses regex conventions common to both .NET and ECMAScript regular-expressions and it also fails even with the RegexOptions.ECMAScript compatibility option.

const String input = @"using System;
using System.Foo;

using Foo.Bar;

namespace Foo
{
    using Baz;

    class Qux
    {

    }
}";

Regex regex = new Regex( @"^using ([\w\.]+)\;$", RegexOptions.Multiline | RegexOptions.ECMAScript );

Match match = regex.Match( input );

Assert.IsTrue( match.Success ); // `match.Success` is false when I run this code

I don't understand why, because the behaviour of \w, ^, $ and the multiline options is ostensibly the same in both platforms.

Here is a screenshot showing it succeeding in Regex101.com:

enter image description here

Here is a screenshot showing it failing in .NET:

enter image description here

Dai
  • 110,988
  • 21
  • 188
  • 277
  • If you use CRLF linebreaks, the dollar matches right between them, so add `\r` right in front. – Sebastian Proske Sep 17 '18 at 05:12
  • 1
    Possible duplicate of [.Net regex matching $ with the end of the string and not of line, even with multiline enabled](https://stackoverflow.com/questions/40058265/net-regex-matching-with-the-end-of-the-string-and-not-of-line-even-with-mult) – Sebastian Proske Sep 17 '18 at 05:14
  • @SebastianProske Argh, thank you. Methinks the maintainers of .NET should add a `RegexOptions.MatchCRLFNewLine`! This design issue is not very well documented in the .NET reference guide. – Dai Sep 17 '18 at 05:16

1 Answers1

2

This is caused by the fact that '$' in multiline mode matches a '\n', not '\r\n', which is the default linebreak on Windows. The solution is simply to add '\r?' in front of the '$' linebreak, like this:

^using ([\w\.]+);\r?$

Now it will match both '\n' and '\r\n'.

Edit:

When you enter a multiline text on RegEx101, they use '\n' as linebreaks, that's why it Works on their site.

Poul Bak
  • 7,390
  • 4
  • 20
  • 40