this is my string com.element.subelement
I want to use propertyregex to replace all . with /, and use that output as a directory path.
It seemed like propertyregex would be the tool for this, but maybe I am using its regexp property incorrectly.
How would I use regex to find the . only, I don't want to assume that the string is 3 alphabet portions separated by periods. also perhaps propertyregex is not the tool for the job
here is one that works where I assume that a package name only have 2 periods
<!-- set package name to folder directory -->
<propertyregex
property="current.target.dir"
input="com.element.subelement"
regexp="(.+?)\.(.+?)\.(.+?)"
replace="\1/\2/\3"
casesensitive="false" />
<echo>${current.target.dir}</echo>
Simply replacing \. with / should accomplish what you're looking for, if I understand. However, this will only replace the first instance on a line by default, so you have to add the property global="true":
<propertyregex
property="current.target.dir"
input="com.element.subelement"
regexp="\."
replace="/"
global="true" />
Related
I have a string with a version as .v_september (every month it will vary). In this i wanted to take the value after underscore, which means "sep" (First 3 letters alone).
By using the regex .v_(.*) i am able to take the complete month and not able to get the first 3 letters alone.
Can someone help me out how can I achieve this in Apache ANT.
Thanks !
Regex functions on properties are a bit awkward in native Ant (as opposed to working with text within files). Ant-contrib has the replaceregexp task, but I try to avoid ant-contrib whenever possible.
Instead, it can be accomplished with the loadfile task and a nested filter:
<property name="version" value=".v_september" />
<loadfile property="version.month.short">
<propertyresource name="version" />
<filterchain>
<tokenfilter>
<replaceregex pattern="\.v_(.{3}).*" replace="\1" />
</tokenfilter>
</filterchain>
</loadfile>
<echo message="${version.month.short}" />
Regarding the regex pattern, note how it needs to end with .*. This is because Ant doesn't have a "match" function that simply returns the content of a capture group. It's just running a replacement, so we need to replace everything in the string that isn't part of the group.
.* will capture everything and for limiting to capturing only three characters you need to write {3} instead of *. Also you should escape the . in the beginning of your regex to only match a literal dot. You can use this regex and capture from group1,
\.v_(.{3})
Demo
I'm looking for an ANT regex to extract string between two _ or between abc_ and _
Below is the regex I'm trying, with no luck.
/xxx/xx_x/xxxx/abc_stringtoextract_x.x.zip
I need to fetch stringtoextract,
<propertyregex property="name"
input="#{process}"
regexp="(?<=abc_)(.*?)(?=\_)"
select="\1"
casesensitive="false"/>
<echo>#{process}</echo>
Replace < with the character entity <. Also the result is saved in the name property specified in the property attribute, and not the process parameter, so you should echo the right result.
<propertyregex property="name"
input="${process}"
regexp="(?<=abc_)(.*?)(?=\_)"
select="\1"
casesensitive="false"/>
<echo>${name}</echo> <!-- instead of process -->
.*abc_([^_]*)
Fixed the issue.
From ant, we want to extract a line from an old /etc/shadow file, capturing the line for a specific user name, such as "manager". This is part of a backup/restore operation. What we used previously was not specific enough, so it would match users like "mymanager", so we tried to tighten it down by anchoring the start of the string to beginning of the line (typically "^"). This definitely did not work as we expected.
How can we anchor so that we get an exact match for a username? -- answered below.
First attempt, which gave the wrong result if we had a user of "mymanager" in the /etc/shadow file copy:
<loadfile property="oldPasswords" srcFile="${backup.dir}/shadow"/>
<propertyregex property="manager.backup" input="${oldPasswords}"
regexp="(manager\:.*)" select="\1" casesensitive="true" />
Second attempt, which failed because "^" is not interpreted in the normal regular expression way by default:
<loadfile property="oldPasswords" srcFile="${backup.dir}/shadow"/>
<propertyregex property="manager.backup" input="${oldPasswords}"
regexp="^(manager\:.*)" select="\1" casesensitive="true" />
Kobi suggested adding -> flags="m" <- which sounded good but ant reported that the flags option is not supported by propertyregex.
The final, successful, approach required inserting "(?m)" at the beginning of the regexp: That was the essential change.
<propertyregex property="manager.backup" input="${oldPasswords}"
regexp="(?m)^manager:.*$" select="\0" casesensitive="true" />
The regexp with propertyregex appears to follow the rules in this documentation of regular expressions in Java (search for "multiline" for example): http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
Check the above document if you have similar questions about how to make propertyregex and regexp do what you want them to do!
THANKS! Solved.
Alan Carwile
I think the m(ultiline) flag is what you want to use and will give the start-of-line anchor the right behavior. It's possible to change flags within the regular expression with the syntax (?<flagstoturnon>-<flagstoturnoff>). So in your case, adding (?m) to the start of the regular expression (before the caret) should work.
I'm running up against my failure to understand regex substitution patterns and Apache Ant's limited documentation on propertyregex. My problem is that I need to take the ${user.name} property and make a lowercase version called ${user.name.lc} but I can't get the replace string correct.
This is what I've got:
<target name="foobar">
<echo>${user.name}</echo>
<propertyregex
property="user.name.lc"
input="${user.name}"
regexp="[A-Z]"
replace="[a-z]"
global="true" />
<echo>${user.name.lc}</echo>
</target>
It finds the upper case portions of the name correctly, but the replacement bombs. This is what I get:
foobar:
[echo] Sally Fields
[echo] [a-z]ally [a-z]ields
I've been googling and reading for about two hours trying different substitution strings. The ant document refers to groupings and shows examples with these. No help for me because there may or may not be groupings in the user name.
Can anyone provide me with what Ant says I need a "regular expression substitition pattern?"
my
Don't use regex for this. There are only a few regex engines which support what you are looking for and I don't think propertyregex is one of them. Use this instead :
<pathconvert property="converted">
<path path="${user.name}"/>
<chainedmapper>
<flattenmapper/>
<scriptmapper language="javascript">
self.addMappedName(source.toLowerCase());
</scriptmapper>
</chainedmapper>
</pathconvert>
<echo>${converted}</echo>
you can use %1> in the replace attribute. > is the standard regex symbol for converting to upper case, so you code will look like :
<propertyregex
property="user.name.lc"
input="${user.name}"
regexp="[A-Z]"
replace="%1>"
global="true" />
Here is a line in my xyz.csproj file:
<Reference Include="SomeDLLNameHere, Version=10.2.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
All I need to do is replace the 'Version=10.2.6.0' to 'Version=11.0.0.0' .
The program I need to do this in is VSBuild which uses VBScript so I believe.
The problem is that I can't hardcode the 'old' version number. I therefore need to replace the following :
<Reference Include="SomeDLLNameHere, Version=10.2.6.0,
I therefor need a regex that will match the above bearing in mind that that in the example quoted, the 10.2.6.0 could be anything.
I believe that a regex that would select the text including and between
'<Reference Include="SomeDLLNameHere' and '>' is what I need.
There are other references to similar requests but none seem top work for me.
I would normally use C# to do this sort of thing and VBScript/Regex is something I avoid like the plague.
For most regex flavors, you would use this:
<Reference Include="SomeDLLNameHere.*?/>
For visual studio, I am not sure if the *? would work... Try this:
\<Reference Include="SomeDLLNameHere[^/]*\/\>
This regex pattern should work
"(<Reference[^>]+Version=)([^,]+),"
Applied with VBScript
str1 = "<Reference Include=""SomeDLLNameHere, Version=10.2.6.0,"
' Create regular expression.
Set regEx = New RegExp
regEx.Pattern = "(<Reference[^>]+Version=)([^,]+),"
' Make replacement.
ReplaceText = regEx.Replace(str1, "$111.0.0.0,")
WScript.echo ReplaceText
Gives the correct result
<Reference Include="SomeDLLNameHere, Version=11.0.0.0,
UPDATE
if you need something that matches between Version= and the end of the tag use > instead of ,
"(<Reference[^>]+Version=)([^>]+)>"
Using Regex with C# or VBScript is pretty much the same because it all comes to developing the regular expression. Something like this could help:
<Reference\s+Include\s*=\s*\".+\",\s*Version\s*=\s*.+,
Not sure what are the rules about case sensitivity and white spaces in csproj files, but this covers the form you described previously. Note that the "+" operator means one or kleen.