2012-09-16 3 views
0

Как я могу использовать RegEx в функции replace, применяемой к строке, для соответствия всем экземплярам подстроки, кроме первого?RegEx - Заменить все, кроме первого совпадения

например. если я заменить все «а», кроме первого, и моя строка:

a b a c b a a b 

Я хочу получить:

a b c b b 

Мой фактическое использование дело в том, что я строю проект с использованием Ant, который объединяет кучу файлов .js в один. Каждый файл javascript начинается с: «use strict». Я только хочу это объявление один раз, поэтому я хочу удалить все экземпляры этой подстроки, кроме одной в начале.

ответ

0

Просто удалите все вхождения "use strict";, а затем снова добавьте его в начале.

Редактировать: Примеры:

  1. sed '/"use strict";/d' <infile> outfile 
    

    становится

    (echo '"use strict"'; sed '/"use strict";/d') <infile> outfile 
    
  2. perl -nie 'print unless /"use strict";/;' file 
    

    становится

    perl -nie 'BEGIN { print qq["use strict";\n]; } print unless /"use strict";/;' file 
    
+0

я сделал рассмотрим это, но я не знаю, как добавить подстроку в файл с помощью Ant, не тратя время на временную копию файла.Я также думал, что добавление этого ограничения в RegEx было бы простым ... – Colin

0

Чтобы решить пример, вы можете использовать отрицательное опережения утверждение:

echo "a b a c b a a b" | perl -pe 's/(?!^)a //g' 

Результаты:

a b c b b 

Чтобы решить проблему проекта (при условии, use strict не происходит несколько раз в каждой строке в вашем объединенном файле), вы можете использовать GNU sed для удаления всех случаев, за исключением первых:

sed '0,/$/!s/use strict//g' file.txt 
1

Вот общее регулярное выражение:

echo "a b a c b a a b" | perl -pWe 's/(?<=(a))(.*?)\1/$2/g' 

Он использует, чтобы проверить назад ', если подходящий шаблон является первым в строке. (В принципе, я имел в виду s/(?<=(a).*?)\1//g, но переменная длина lookbehind, похоже, не широко реализована). Существует недостаток - он будет производить вывод, как

a b c b b 

Чтобы сделать это аккуратно, вы можете использовать

echo "a b a c b a a b" | perl -pWe 's/(?<=(a\s))(.*?)\1/$2/g' 

, но это не будет удалить последний a на входе, как a b a c b a a

+0

Хотя это отлично работает в perl, кажется, что утверждения lookbehind не поддерживаются командой replaceregexp от Ant: 'Значение атрибута " соответствует ", связанного с типом элемента " null " не должен содержать символ «<». – Colin

Смежные вопросы