intl
intl

Reputation: 2773

Regular Expression rename

I am writing an Ant script that moves the contents of one directory to another one. In addition to just moving the files, I also have to rename the files.

There are some files that have the structure name1_ab_cd.properties and some files have the structure name2_ab.properties. What I essentially have to do is remove everything from the first _ until the end and replace it with properties.

So, the files must be named like name1.properties and name2.properties. Currently, my implementation is as follows:

<mapper type="regexp" from="(.*)_.*_.*(.*)" to="\1.properties\2" />

This works for files that have two _'s, but not for the ones that have one _ . name1_ab_cd.properties would be renamed to name1.properties, however, name2_ab.properties would remain as is. If I make it like so:

<mapper type="regexp" from="(.*)_.*(.*)" to="\1.properties\2" />

then, only name2_ab.properties would be renamed to name2.properties, however, name1_ab_cd.properties would remain as is.

I need a way to just select the first _ and then select until the end of the string. How would I go about doing this?

Thanks

Upvotes: 2

Views: 2397

Answers (2)

David W.
David W.

Reputation: 107040

Regular expressions are greedy. That is, they'll match the largest possible match. Imagine a string like this:

this_is_a_test

and I want the first part to the first underscore:

this_is_a_test =~ s/^(.*)_/$1/

The parentheses set won't just match this, but this_is_a_test because that's the largest match. That's because I am telling it to match everything up to an underscore.

The basic way around something like that is to exclude the character I don't want. For example:

this_is_a_test =~ s/^([^_]*)_/$1/

Replaces the .* which matches any series of characters to [^_]* which matches any series of characters except underscores. That way, you're only matching up to the first underscore.

In fact, we could eliminate the underscore after the grouping:

this_is_a_test =~ s/^([^_]*)/$1/

So, all you have to do is change your mapper from:

<mapper type="regexp" from="(.*)_.*(.*)" to="\1.properties\2" />

to

<mapper type="regexp" from="^([^_]*).*\.properties$" to="\1.properties"/>

The ^([^_]*) will match everything from the beginning of the line until the first underscore. The \.properties$ will make sure the file name ends with .properties.

I'm not sure what your second grouping was doing. (Are you trying to move part of the string after the .properties suffix?) Instead, I just did it as you stated in your initial query.

Upvotes: 0

Qtax
Qtax

Reputation: 33908

Try this:

<mapper type="regexp" from="([^_.]+)[^.]*(\.properties)" to="\1\2" />

Upvotes: 2

Related Questions