Регулярное выражение совпадения и замены - PullRequest
0 голосов
/ 09 июля 2011

Я пишу скрипт 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 ]

2 голосов
/ 09 июля 2011

Отредактировано 10 июля 2011 года для включения отличных предложений inTide:

Как насчет

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

Это оставит фиктивную оканчивающуюся запятую для «черт» - последний выбор. Удалить это второй проход:

match="(this.property.*?)(?:,$|$)"
replace="\1"
1 голос
/ 19 июля 2011

Это не так сложно, как кажется. Следующее работает для всех случаев, кроме случаев, когда ключевое слово является единственным. (И для этого случая просто добавьте другое правило.)

<replaceregexp  file="@{targetDir}/setup/properties/abc.properties"
match="this\.property=(.*)(?:,tiger\b|\btiger,)(.*)"
replace="this.property\1\2"/>
1 голос
/ 19 июля 2011

Как насчет чего-то вроде

<replaceregexp
    file="@{targetDir}/setup/properties/abc.properties"
    match="(this.property.*)(?:@{toRemove},|,@{toRemove})"
    replace="\1"
/>
1 голос
/ 09 июля 2011

Я попробовал несколько регулярных выражений, но не получил один для всех, ближайший был:

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

обратите внимание на трейлинг ',' после обезьяны

case first item = обезьяна, вы должны использовать:

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

, чтобы избавиться от ', в противном случае с:

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

вы получите

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

с использованием завершающего ',' после того, как удаляемый элемент будет работать для всех остальных элементов, например, банан, но не для
для последнего элемента.

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.

После макроопределения, работающего для всехслучаи, в которых используются 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>
1 голос
/ 09 июля 2011

Попробуйте использовать это:

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

Обновление: Чтобы удалить только одну из возможных окружающих запятых, требуется немного больше работы. Если регулярное выражение lib, которое вы используете в Ant, поддерживает условные выражения, вы можете решить его с помощью чего-то вроде (?(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="
1 голос
/ 09 июля 2011

Будет ли это работать?

<!-- 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"/>

Я признаю, что это клочок (и вам понадобится третий случай, когда тигр - единственный элемент в списке), но он может справиться с работой.

0 голосов
/ 09 июля 2011

Добавление пользовательской задачи муравья, которая напрямую работает с файлом свойств, будет более надежным.(муравей может вызывать Java-программу, так что это может быть другой вариант).Поскольку ant позволяет использовать Java-программы внутри javascript (носорога), я попробовал приведенный ниже код.

0 голосов
/ 09 июля 2011

В 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=
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...