I can't seem to figure out the regex replace syntax

Running FileBot from the console, Groovy scripting, shell scripts, etc
Post Reply
RDeNatale
Posts: 5
Joined: 24 Feb 2015, 17:08

I can't seem to figure out the regex replace syntax

Post by RDeNatale »

I'm trying to use the replace script to change from having one flat movie directory to subdirectories for each movie. But I can't seem to grok what's happening with the groovy replacement string syntax. I've tried various things but nothing seems to get me there.

For example:

Code: Select all

filebot.sh -script fn:replace --action test --def "e
=([\\^.]*?)([.].*)$" "r=\\$1/\\$1\\${2}" /volume1/video/movie
Which I looks like it has two capture groups one of which matches the filename without the extension, and the second one the extension, then the replace string is trying to make a directory from the filename and put the original file there

but this produces renames like this:

Code: Select all

[TEST] Rename [/volume1/video/movie/The Wild Bunch 1969.m4v] to [/volume1/video/movie/The Wild Bunch 1969/\]
As has everything else I've tried.

I noticed the GOTCHA section on this page http://groovy.codehaus.org/Regular+Expressions which led me to try various combinations of $1, ${1} etc. none of which seems to work.
User avatar
rednoah
The Source
Posts: 23931
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: I can't seem to figure out the regex replace syntax

Post by rednoah »

So you're on Linux? Writing a shell script? Keep $variables in mind. The shell interpreter will replace $1 $2 etc with arguments which are probably empty thus $1 $2 etc will be empty.

You want to pass along the literal $ so you need to escape things even more. :D

@see http://www.filebot.net/forums/viewtopic.php?f=4&t=1899

Use -script fn:sysenv to see what values you're actually passing along. ;)
:idea: Please read the FAQ and How to Request Help.
RDeNatale
Posts: 5
Joined: 24 Feb 2015, 17:08

Re: I can't seem to figure out the regex replace syntax

Post by RDeNatale »

rednoah wrote:So you're on Linux? Writing a shell script? Keep $variables in mind. The shell interpreter will replace $1 $2 etc with arguments which are probably empty thus $1 $2 etc will be empty.

You want to pass along the literal $ so you need to escape things even more. :D

@see http://www.filebot.net/forums/viewtopic.php?f=4&t=1899

Use -script fn:sysenv to see what values you're actually passing along. ;)
Thanks, that got me a bit further along, but I'm still having problems figuring out what to pass as the replacement.

After some playing around, it seems that the replace script was already using the movie name without extension as a subdirectory name, not sure why.

Code: Select all

filebot.sh -script fn:replace --action test --def "e
=([\^.]*?)([.].*)\$" "r=/xxx" /volume1/video/movie
is giving renames like:

Code: Select all

[TEST] Rename [/volume1/video/movie/Wuthering Heights 1939.m4v] to [/volume1/video/movie/Wuthering Heights 1939/xxx]
So I changed the replacement string to only provide the filename:

Code: Select all

filebot -script fn:replace --action test --def "e
=([\^.]*?)([.].*)\$" "r=/\\\$1\\\$2" /volume1/video/movie
and I'm getting this:

Code: Select all

[TEST] Rename [/volume1/video/movie/Wuthering Heights 1939.m4v] to [/volume1/video/movie/Wuthering Heights 1939/$1$2]
Here's what sysenv shows for the last command:

Code: Select all

# Arguments #
args[0] = -script
args[1] = fn:sysenv
args[2] = --action
args[3] = test
args[4] = --def
args[5] = e=([\^.]*?)([.].*)$
args[6] = r=/\$1\$2
args[7] = /volume1/video/movie
I'm still not grokking what's going on here.
User avatar
rednoah
The Source
Posts: 23931
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: I can't seem to figure out the regex replace syntax

Post by rednoah »

You're passing in /\$1\$2 and you probably want to pass in /$1$2.

@see http://docs.oracle.com/javase/8/docs/ap ... ng.String-

I'm sure you'll get the escaping right through trial and error.
:idea: Please read the FAQ and How to Request Help.
RDeNatale
Posts: 5
Joined: 24 Feb 2015, 17:08

Re: I can't seem to figure out the regex replace syntax

Post by RDeNatale »

rednoah wrote:You're passing in /\$1\$2 and you probably want to pass in /$1$2.

@see http://docs.oracle.com/javase/8/docs/ap ... ng.String-

I'm sure you'll get the escaping right through trial and error.
Something strange is happening here. It appears as if the pattern match is resetting the capture groups before I can use them.

First, I tested the regex using Ruby, which has pretty much the same regex syntax as java, but a slightly different way of referring to back references (\ instead of $)

Code: Select all

1.9.3-p429 :024 > pat = /(([^.]*)([.].*))$/
 => /(([^.]*)([.].*))$/
1.9.3-p429 :025 > "Wuthering Heights 1939.m4v".gsub(pat, '\\2/\\1')
 => "Wuthering Heights 1939/Wuthering Heights 1939.m4v"
The first capture group gets the entire file name, while the second only gets the filename sans extension.

So I reworked the replacement string to java format:

Code: Select all

filebot.sh -script fn:sysenv --action test --def "e=(([\^.]*)[.].*)\$" "r=\$2/\$1"/volume1/video/movie

args[5] = e=(([\^.]*)[.].*)$
args[6] = r=$2/$1
But this still doesn't work.

Code: Select all

[TEST] Rename [/volume1/video/movie/Wuthering Heights 1939.m4v] to [/volume1/video/movie/Wuthering Heights 1939/.m4v]
So a change for debugging change the replacement to > 2: '$2' / 1: '$1' **

Code: Select all

filebot.sh -script fn:replace --action test --def "e=(([\^.]*)[.].*)\$" "r= > 2: '\$2' / 1: '\$1' **" /volume1/video/movie

[TEST] Rename [/volume1/video/movie/Wuthering Heights 1939.m4v] to [/volume1/video/movie/Wuthering Heights 1939> 2: '' / 1: '.m4v' **]
I'm certain that I'm quoting the replacement correctly, if I use \\\$2 instead of \$2 the replacement string has $2 instead of an empty string

It looks like the first capture is being reset before the replacement string gets to it. I still don't understand where the directory name is coming from:

Code: Select all

/volume1/video/movie/Wuthering Heights 1939.m4v to 
/volume1/video/movie/Wuthering Heights 1939> 2: '' / 1: '.m4v' **
I see in the replace script where the pattern and replacement strings are used:

Code: Select all

renamePlan[f] = pattern.matcher(f.path).replaceAll(r) as File
But I don't understand what's happening inside FileBot itself.
User avatar
rednoah
The Source
Posts: 23931
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: I can't seem to figure out the regex replace syntax

Post by rednoah »

The code definitely works:

Code: Select all

def e = /(\w)(\d)/
def r = /$0 => $2$1/
def pattern = Pattern.compile(e, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)

def output = pattern.matcher('X5').replaceAll(r)
println output

Code: Select all

X5 => 5X
I'd play with this code first until you get your regex/replacement right.
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 23931
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: I can't seem to figure out the regex replace syntax

Post by rednoah »

I think your regex might be misguided somewhere. Also I don't think that using this script and regex is the best way to solve this particular problem. Here's my regex/replace solution though. :ugeek:

Code: Select all

def f = '/volume1/video/movie/Wuthering Heights 1939.m4v' as File
def e = /([^\/\.]+)[.](\w{3})$/
def r = '$1/$1.$2'
def pattern = Pattern.compile(e, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE)

def output = pattern.matcher(f.path).replaceAll(r) as File
println output.path

Code: Select all

/volume1/video/movie/Wuthering Heights 1939/Wuthering Heights 1939.m4v
:idea: Please read the FAQ and How to Request Help.
Post Reply