2

I’m trying to create a valid RegEx replacement pattern for correctly formatting specific .XML file names. Specifically, if a file name does not begin with a prefix, let’s say, ACE_. If the XML file name and extension does not begin with ACE_, prepend the string ACE_ to the file name. For example, if my input source string is the following:

Widgets.xml

I would like to execute a single RegEx Replacement that would result in the string being:

ACE_Widgets.xml.

Conversely, if the string already begins with ACE_, I would like it to remain unchanged.

Also, how can I include the pattern “.xml” to ensure that the string pattern for the file name and extension ends with “.xml” in the same matching pattern for the RegEx Replacement pattern?

As for the match, I have some luck with the following:

^ACE_{1}[\d\D]+

Which indicates there is a match for the pattern if the input string is ACE_Widgets.xml and no match if the string is Widgets.xml

The RegEx pattern would suffice, but if you need to know the language in which I’d like to use the replacement pattern is in .NET 4.0 in either C# or VB.NET.

The following posting is close to what I’m looking for, but with the inclusion of the *ix directory path prefix, and the use of preg_replace() in PHP, I’m having a bit of a struggle getting it to work with what I need to do:

Regular Expression: How to replace a string that does NOT start with something?

As always, thank you in advance for your time, help and patience. They are very much appreciated…

Community
  • 1
  • 1
ClockEndGooner
  • 672
  • 1
  • 12
  • 24

4 Answers4

6

Actually regex is a pretty clean way to accomplish this. Here is a solution with a regex written in free-spacing mode with lots-o comments:

text = Regex.Replace(text, @"
    # Match XML file names not starting with: ACE_
    ^          # Anchor to start of string.
    (?!ACE_)   # Assert does not start with ACE_
    .*         # Match filename up to extension.
    (?i)       # Make case insensitive for .xml
    \.xml      # Require XML file extension.
    $          # Anchor to end of string.", 
    "ACE_$0", RegexOptions.IgnorePatternWhitespace);

Note that this assumes that the ACE_ prefix requirement is case sensitive.

ridgerunner
  • 33,777
  • 5
  • 57
  • 69
  • Many, many thanks, ridgerunner. The explanations on the replacement pattern helped tremendously, and the code fragment is spot on. I was able to implement it with my colleague easily. Again, my thanks to everyone for their input. – ClockEndGooner Oct 10 '11 at 17:04
  • Some people might really not agree with me, but I would never pass a code review with a regex that couldnt be done in a more readable and easier to expand fashion within the base language, such as StartsWith –  Mar 20 '15 at 19:22
  • I totaly agree with @user1043000. Regex is, in my opinion, never a clean way of doing something. Maybe performant, maybe short, but not clean or clear. – bnu Sep 13 '17 at 08:22
4

There is no need for regex here:

var fileName = …;
var prefix = "ACE_"
if (!fileName.StartsWith(prefix))
    fileName = prefix + fileName;

If you want to add checking for the .xml extension too, add:

var extension = ".xml";
if (!fileName.EndsWith(extension))
    fileName = fileName + extension;
svick
  • 236,525
  • 50
  • 385
  • 514
  • Hi, svick; Thank you for your suggestion. Using the String.StartsWith() is along the same lines as yas4891 suggessted, and as I mentioned, I too recommended to my colleague that he use String.StartsWith(); but his current code base requires the use of RegEx.Replace(). – ClockEndGooner Oct 10 '11 at 15:38
  • As I said in my other comment: such limitation doesn't make any sense. And if it really is in the code you have, change the code. – svick Oct 10 '11 at 15:40
3

If RegExp is not a specific requirement I suggest you use String.StartsWith() function instead, as it reads more naturally.

var filename = "Widget.xml";
if(!filename.StartsWith("ACE_"))
{
    File.Move(filename, Path.Combine(Path.GetDirectoryName(filename), string.Format("ACE_{0}", Path.GetFileName(filename)))); 
}
yas4891
  • 4,774
  • 3
  • 34
  • 55
  • Yas4891: Thank you for the feedback; I posted my question on behalf of a colleague here in our office. I too recommended that he also use String.StartsWith(), but with his current code base, he is required to update the file name string using RegEx.Replace(). Again, thank you for the suggestion... – ClockEndGooner Oct 10 '11 at 15:36
1

And these days in c#6

var fileName = "Widgets.xml"; // or "ACE_Widgets.xml"
var prefix = "ACE_"
fileName = fileName.StartsWith(prefix) ? fileName : $"{prefix}{fileName}";
chrisp_68
  • 1,731
  • 23
  • 41