正则表达式匹配和替换

时间:2011-07-08 20:37:47

标签: regex ant

我正在编写一个Ant脚本,用于从属性文件中删除内容。

假设属性文件名为abc.properties,其中一个属性是这样的:

this.property=monkey,banana,peanuts,ate,tiger,what,the,heck

我的脚本必须能够在不影响订单的情况下删除其中一个项目。现在,我有这个:

<replaceregexp  file="@{targetDir}/setup/properties/abc.properties"
match="this.property(.*),tiger(.*)"
replace="this.property\1\2"/>

目前,正则表达式适用于除猴子之外的任何事情。我可以用什么,花生或除猴子以外的任何东西取代老虎,因为它们都在他们面前有逗号。如果我从匹配表达式中删除了逗号,则会有一个额外的逗号。问题是,我将如何编写将替换任何项目的正则表达式,包括猴子?

由于

8 个答案:

答案 0 :(得分:2)

2011年7月10日编辑,纳入了有关inTide的优秀建议:

怎么样

match="this.property(.*[=,])tiger(?:,|$)(.*)"
replace="\1\2"

这将留下一个伪造的“逗”的逗号 - 最后的选择。删除这是第二遍:

match="(this.property.*?)(?:,$|$)"
replace="\1"

答案 1 :(得分:1)

这会有用吗?

<!-- Handle the case when tiger is first -->
<replaceregexp  file="@{targetDir}/setup/properties/abc.properties"
match="this.property=tiger,(.*)"
replace="this.property=\1"/>

<!-- Handle all other cases -->
<replaceregexp  file="@{targetDir}/setup/properties/abc.properties"
match="this.property=(.*),tiger(.*)"
replace="this.property=\1\2"/>

这是一个kludge,我承认(并且你需要第三个案例来处理当Tiger是列表中唯一的项目时),但它可能会起作用。

答案 2 :(得分:1)

尝试使用:

match="(this.property=(?:.*,)?)tiger(?:,|$)" replace="\1"

更新:要删除一个可能的周围逗号,需要更多的工作。如果你在Ant支持的条件中使用正则表达式lib,你可以借助(?(2),)之类的东西来解决它。但由于你可能正在使用Javas默认的Regex lib,你必须使用交替,例如:

match="(this.property=(?:[^,]*(?:,[^,]*)*)?)(?:,tiger(?=,|$)|(?<==)tiger(?:,|$))" replace="\1"

Perl测试:

my @strings = (
    'this.property=monkey,banana,peanuts,ate,tiger,what,the,heck',
    'this.property=monkey,banana,peanuts,ate,tiger',
    'this.property=tiger,what,the,heck',
    'this.property=tiger',
    );


my $re = qr/(this.property=(?:[^,]*(?:,[^,]*)*)?)(?:,tiger(?=,|$)|(?<==)tiger(?:,|$))/;

for(@strings){
    print ">> \"$_\"\n";
    s/$re/$1/g;
    print "   \"$_\"\n";
}

输出:

>> "this.property=monkey,banana,peanuts,ate,tiger,what,the,heck"
   "this.property=monkey,banana,peanuts,ate,what,the,heck"
>> "this.property=monkey,banana,peanuts,ate,tiger"
   "this.property=monkey,banana,peanuts,ate"
>> "this.property=tiger,what,the,heck"
   "this.property=what,the,heck"
>> "this.property=tiger"
   "this.property="

答案 3 :(得分:1)

我尝试了几个正则表达式,但没有得到一个,最接近的是:

 <replaceregexp  file="props.txt"
  match="(this.property=[,?\w+,?]*)monkey,(.*)"
  replace="\1\2"
 />

注意猴子后面的',',

案例第一项=猴子,你必须使用:

match="(this.property=[,?\w+,?]*)monkey,(.*)"<br>

摆脱','否则:

match="(this.property=[,?\w+,?]*)monkey(.*)"

你会得到

 this.property=,banana,peanuts,ape,tiger,what,the,heck

在shold被删除的项目之后使用尾随','将适用于所有其他项目,例如:香蕉也是,但不是 最后一项。

case last item = heck:

match="(this.property=[,?\w+,?]*)heck,(.*)"

不会做任何事情

match="(this.property=[,?\w+,?]*)heck(.*)"

会得到:

this.property=monkey,banana,peanuts,ape,tiger,what,the,

仅限:

match="(this.property=[,?\w+,?]*),heck"

会起作用。

所以,没有通用的解决方案,因为','

的问题

因为必须使用多个步骤,才能使其适用于所有情况 因此,要么使用多个replaceregexp部件,要么反过来使用,意味着加载属性文件,然后直接编辑属性 - propertyfile保持不变。
由于ant中的属性在设计上是不可变的,因此您必须使用一些Ant Addon或一种可以访问ant api的脚本语言来实现此目的。

使用macrodef处理所有案例,使用Flaka

<project xmlns:fl="antlib:it.haefelinger.flaka">

 <property name="this.property" value="monkey,banana,peanuts,ape,tiger,what,the,heck"/>

 <macrodef name="editcsvproperty">
  <attribute name="csvproperty"/>
  <attribute name="newproperty"/>
  <attribute name="delete"/>
   <sequential>
    <fl:when test="'@{csvproperty}' eq '@{newproperty}'">
     <echo>Overriding existing property => '@{csvproperty}' !!</echo>
    </fl:when>
    <fl:let>
     ; first delete item itself
     @{newproperty} ::= replace(property['@{csvproperty}'], '', '@{delete}')
     ; take care of doubled ,,
     @{newproperty} ::= replace(property['@{csvproperty}'], ',', ',,')
     ; take care of a leading ,
     @{newproperty} ::= replace(property['@{csvproperty}'], '$1', '^,(.+)')
     ; take care of a trailing ,
     @{newproperty} ::= replace(property['@{csvproperty}'], '$1', '(.+),$')
    </fl:let>
   </sequential>
 </macrodef>


 <editcsvproperty
    csvproperty="this.property"
    newproperty="this.property"
    delete="heck"
 />

 <echo>$${this.property} => ${this.property}</echo>
</project>

答案 4 :(得分:1)

这样的东西
<replaceregexp
    file="@{targetDir}/setup/properties/abc.properties"
    match="(this.property.*)(?:@{toRemove},|,@{toRemove})"
    replace="\1"
/>

答案 5 :(得分:1)

这并不像看起来那么难。以下适用于所有情况,除非关键字是唯一的情况。 (对于这种情况,只需添加另一条规则。)

<replaceregexp  file="@{targetDir}/setup/properties/abc.properties"
match="this\.property=(.*)(?:,tiger\b|\btiger,)(.*)"
replace="this.property\1\2"/>

答案 6 :(得分:0)

在Python中,我会这样做:

import re

ch = 'this.property=monkey,banana,tigerfish,peanuts,ate,tiger,what,the,heck'
print ch
print '-----------------------------------------------------------'

for word in ('tiger','heck','monkey'):
    regx = re.compile('(?<=this\.property=)(.*?)(,)?%s(?(2)(?=(?:,|$))|,)(.*)' % word, re.M)
    print 'word=='+word
    print regx.sub('\\1\\3',ch)
    print


print
ch = 'this.property=monkey'
print ch
print '-----------------------------------------------------------'
regx = re.compile('(?<=this\.property=)(.*?)(,)?%s(?(2)(?=(?:,|$))|(?:,|$))(.*)' % 'monkey', re.M)
print 'monkey'
print regx.sub('\\1\\3',ch)

结果

this.property=monkey,banana,tigerfish,peanuts,ate,tiger,what,the,heck
-----------------------------------------------------------
word==tiger
this.property=monkey,banana,tigerfish,peanuts,ate,what,the,heck

word==heck
this.property=monkey,banana,tigerfish,peanuts,ate,tiger,what,the

word==monkey
this.property=banana,tigerfish,peanuts,ate,tiger,what,the,heck


this.property=monkey
-----------------------------------------------------------
monkey
this.property=

答案 7 :(得分:0)

添加直接与属性文件一起使用的自定义ant任务将更加坚固。 (ant可以调用java程序,因此可能是另一种选择)。由于ant允许在javascript(rhino)中使用java程序,我试过下面的代码..你可以根据需要进行调整..

<project name="blah" default="editprops" basedir=".">
    <target name="editprops" >
        <property file="try.props"/>

        <script language="javascript"> <![CDATA[
              importClass(java.util.Properties);
              importClass(java.io.FileReader);
              importClass(java.io.FileWriter);
              importClass(java.io.IOException);
              var properties = new Properties();
              var reader = new FileReader("try.prop");
              properties.load(reader);
            var tt = properties.getProperty("this.property");
            var ll= tt.split ( ",");
            var newval="";
            var i=0;
            for ( i =0; i< ll.length ; i++ ) {
                if ( ll[i] == "monkey" ) {
                    continue;
                }
                if ( newval=="" ) {
                    newval =  ll[i];
                }
                else {
                    newval = newval + "," + ll[i];
                }


            }
            print ( newval);
            properties.setProperty("this.property", newval);
            var writer = new FileWriter ( "try.new");
            properties.store( writer, "today" );

            ]]></script>
    </target>
</project>
相关问题