I need to write a regex to match an element in a comma-separated list, ignoring whitespaces near ,
.
For example:
elem1, elem2 ,elem3, elem4 ,elem5 ,elem6
Any of: elem1
elem2
elem3
elem4
elem5
elem6
should match.
The trailing comma (before end of line) is not allowed.
I tried this pattern:
pattern="(^|/,)\s*@{value}\s*(/,|$)"
but it doesn't work. (False negative)
How can i do that pattern? What's wrong in mine?
Thanks.
Interpolation is your problem. And, you can't consume the ',' on both sides, you can only consume it on one side.
Edit - That is if you are searching in a global sense, then you can't consume a comma on both sides. For instance if you want to find ALL of something. If its just find the first match only then a comma on both sides is OK. I don't know about java but, you can't just plop a list into a regex and expect it to match unless its set up as an alternation first. Like "(?:^|,)\\s*(?:elem4|elem6)\\s*(?=,|\$)"
. For sure you need another escape on the whitespace \\s
.
$value = '(elem.)';
$rx = "(?:^|,)\\s*$value\\s*(?=,|\$)";
or
$rx = '(?:^|,)\s*(elem.)\s*(?=,|$)';
In Perl:
use strict;
use warnings;
my $value = '(elem.)';
my $str = ' elem1, elem2 ,elem3, elem4 ,elem5 ,elem6 ';
my $rx = "(?:^|,)\\s*$value\\s*(?=,|\$)";
while ( $str =~ /$rx/g ) {
print "'$1'\n";
}
Output
'elem1'
'elem2'
'elem3'
'elem4'
'elem5'
'elem6'
From your previous question, you want to test, if a csv list contains a special value. This is a different task - and a different ant task too:
<macrodef name="csvcontains">
<attribute name="value"/>
<attribute name="list"/>
<attribute name="casesensitive" default="false"/>
<sequential>
<condition property="matched" else="false">
<contains string="@{list}" substring="@{value}" casesensitive="@{casesensitive}"/>
</condition>
</sequential>
</macrodef>
(You may think about renaming the property matched
to contained
)
I found one solution:
The pattern is:
^(.+,\s*|\s*)@{value}(\s*|\s*,.+)$
An usage example is:
<macrodef name="csvcontains">
<attribute name="value"/>
<attribute name="list"/>
<attribute name="propertyName"/>
<attribute name="casesensitive" default="false"/>
<sequential>
<condition property="@{propertyName}" else="false">
<or>
<isset property="@{propertyName}"/>
<matches string="@{list}" pattern="^(.+,\s*|\s*)@{value}(\s*|\s*,.+)$" casesensitive="@{casesensitive}"/>
</or>
</condition>
</sequential>
</macrodef>