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" />
Related
i am trying to verify a xml structure, where i want to check that the ns22:statement true tag is found after the postcode DataItem.
<ns21:DataItem name="country" default="false" />
<ns21:DataItem name="postcode" default="false">
<ns22:statement disabled>true</ns22:statement>
</ns21:DataItem>
I have tried this
(?m)\b.*:DataItem name="postcode" (?s)\b.*>$\n.*\bstatement disabled>true\b
but when changing postcode to country (where is supposed not to return anything) it catches all tags country, postcode and statement true.
I have also created this https://regexr.com/3quso
Any suggestions of how to get only the postcode+statement true??
XPath really does look like the best tool for the job given you're trying to validate XML structure as well as content. So, ignoring namespaces, you could use the following XPath in a soapUI XPath Match assertion:
boolean(//*[local-name()='DataItem'][#name='postcode']/*[local-name()='statement' and .='true'])
Also, in <ns22:statement disabled>true</ns22:statement>, is disabled meant to be part of the element name or an attribute? As it stands, it makes the XML invalid, so I've ignored it.
For good reasons not to use regular expressions to parse XML/HTML, see Why it's not possible to use regex to parse HTML/XML: a formal explanation in layman's terms
I need to replace different values of receiveTimeOut attribute with a receiveTimeOut="59:59:59"
Can wild card search be used to achieve this task, in Visual Studio?
<endpoint receiveTimeOut="10:10:20" someOtherProperty="x1" yetAnotherProperty="y1" />
<endpoint receiveTimeOut="10:50:20" someOtherProperty="x2" yetAnotherProperty="y2" />
...
<endpoint receiveTimeOut="30:50:20" someOtherProperty="x3" yetAnotherProperty="y3" />
I tried: using wildcard option in Find & Replace dialog, receiveTimeOut="*" but this selects complete line, receiveTimeOut="10:10:20" someOtherProperty="x1" yetAnotherProperty="y1" />
As you might have guessed, I am editing WCF service web.config and have to do this task manually & repeatedly.
Using the regex option...
Find: <endpoint receiveTimeOut="[^"]+"
Then...
Replace: <endpoint receiveTimeOut="59:59:59"
The [^"]+ part uses a negative character class that matches any character except for a double quote. The + will match it one or more times.
It turns out that this is actually quite simple to do with a regular expression.
Just use .* for your wildcard and check Use regular expressions.
For example, I have some grids and I want to find columns with an attribute of Visible="False" so a string might be:
telerik:GridBoundColumn name="name" Visible="False"
My search string would be: "GridBoundColumn.*Visible="False""
Done.
Ahmad's is the way to go. But as a naive and bit different alternative, one could search:
receiveTimeOut="[0-9]*\:[0-9]*\:[0-9]*"
This requires the data between the double quotes of the receiveTimeOut value has two colons (which are escaped) with any number of digits about them.
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" />
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.
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.