A question about rename scripting and RegEx

I am learning RegEx for rename scripting (Hey Leo, thanks for your very useful tutorial, RegExp basics: Removing characters from start/end of names).

In exercise, I wrote a script to replace dash with dot, just if a dash occurred between two numbers.

Sample file name :[b] Test_v1-2-3-4-5.txt[/b]
Expected file name: [b]Test_v1.[/b]

The code was as follow:

@script vbscript
option explicit

Function Rename_GetNewName (strFileName, strFullPath, fIsFolder, strOldName, ByRef strNewName)

  Dim regex
  Dim strExtension
  Dim strNameOnly

  Set regex = new RegExp
  regex.IgnoreCase = true ' Ignore Case-sensitive matching.
  regex.Global = true ' All matches will be replaced, not just the first match.
  If fIsFolder or 0 = InStr(strFileName,".") then
    strExtension = ""
    strNameOnly = strFileName
    strExtension = Right(strFileName, Len(strFileName)-(InStrRev(strFileName,".")-1))
    strNameOnly = Left(strFileName, InStrRev(strFileName,".")-1)
  End If

  ' Replace Dashes with dots (just between numbers)
    regex.Pattern = "([0-9])-([0-9])"
    strNameOnly = regex.Replace(strNameOnly, "$1.$2")

    strNewName = strNameOnly & LCase(strExtension)
End Function

The output of above code was:


As you see, the dashes after 2 and 4 were not replaced with dot. Is my pattern incorrect?

I know, the problem is solved if I call the same regex.Replace() twice, but I want to learn not swing the lead. :laughing:

Best Regards

I remember that : [Regexp help)

So if i choose regxp :

old name : (.)(.)-(.*)#
new name : \1\2.\3

but i'm failed with a script :cry:

I might be wrong but that looks like a bug in VBScript's regexp handling. Perhaps it is supposed to work like that but it seems wrong to me.

As AlbatorIV shows, you don't need to use VBScript at all to get what you want.

If you do want to use VBScript then I recommend applying the regexp repeatedly, adding each version of the string to a list (or a dictionary if you want to be fancy), and stopping when the result you get is one you have already seen.

It's tempting to just store the previous version of the string and keep applying the regexp until it stops changing the string, but you can get yourself into an endless loop doing that. It's possible to make a regexp which cycles through two or more strings, meaning each iteration creates a change but the string will never become stable.

Thanks for the reply,
When char # is used, I think the follow will be enough:

old name : (.)-(.)#
new name : \1.\2

What is the extra (.*) for?

Best Regards

Thanks dear leo,
After your letter, I have a new question too :laughing:
Can I use # char on VBScript? If yes, what is the syntax?

Best Regards

[quote="searcher123"]old name : (.)-(.)#
new name : \1.\2
What is the extra (.*) for?[/quote]
Nothing :smiley:

Why? because when we use # in old name, regexp become 'find&replace' so others strings are missing.

As far as I know, the equivalent is the regex.Global = true, which you are already using. You'll have to code up a loop, I think.

Just notice that my last regexp replace "-" by "." between 2 characters, not only numbers. With this it's ok...

old name : (.[0-9])-(.)#
new name : \1.\2

[quote="AlbatorIV"]Just notice that my last regexp replace "-" by "." between 2 characters, not only numbers. With this it's ok...

old name : (.[0-9])-(.)#
new name : \1.\2[/quote]
Hi AlbatorIV,
this last RegExp isn't perfect actually because it replaces "-" by "." for any numbers followed by any characters, in this example, it should fail like this:

I think the correct one should be:
old name : (.[0-9])-([0-9].)#
new name :\1.\2
I suspect you missed the "[0-9]" when you typed the expression

oops, where is the edit button?

I just forgot the "+" in the expression

old name : (.[0-9]+)-([0-9]+.)#
new name :\1.\2

It is needed if the file name is something like this Test_v1-20-35-4-5-a-1-8-b.txt

Yes good catch... :wink: