2015-07-14 9 views
2

Я использую Perl для создания прототипов.perl Regex заменить для определенной длины строки

Мне нужно выражение, чтобы заменить e на [ee], если строка ровно 2 символа и заканчивается буквой «e».

le -> l [ee] 
me -> m [ee] 
elle -> elle : no change 

Я не могу проверить длину строки, мне нужно одно выражение, чтобы выполнить всю работу.

Я пробовал:

`s/(?=^.{0,2}\z).*e\z%/[ee]/g` but this is replacing the whole string 
`s/^[c|d|j|l|m|n|s|t]e$/[ee]/g` same result (I listed the possible letters that could precede my "e") 
`^(?<=[c|d|j|l|m|n|s|t])e$/[ee]/g` but I have no match, not sure I can use^on a positive look behind 

EDIT Ребята вы изумительны, часы поиска в Интернете и здесь я получаю ответы минут после того, как я отправил.

Я перепробовал все свои решения, и они работают отлично непосредственно в моем сценарии, то это:

my $test2="le"; 
$test2=~ s/^(\S)e$/\1\[ee\]/g; 
print "test2:".$test2."\n"; 
-> test2:l[ee] 

Но я погрузкой этих регулярных выражений из текстового файла (с помощью Perl для прото, идея состоит в том, чтобы использовать его с любым языком, реализующего регулярное выражение):

в текстовом файле я хранить, например (я использовал% разделить линию между спичкой и заменить):

^(\S)e$% \1\[ee\] 

и Затем я разобрать и применить все регулярное выражение так:

my $test="le"; 
while (my $row = <$fh>) { 
    chomp $row; 
    if($row =~ /%/){ 
     my @reg = split /%/, $row; 
     #if no replacement, put empty string 
     if($#reg == 0){ 
      push(@reg,""); 
     } 
     print "reg found, reg:".$reg[0].", replace:".$reg[1]."\n"; 
     push @regs, [ @reg ]; 
    } 
} 
print "orgine:".$test."\n"; 
for my $i (0 .. $#regs){ 
    my $p=$regs[$i][0]; 
    my $r=$regs[$i][1]; 
    $test=~ s/$p/$r/g; 
} 
print "final:".$test."\n"; 

Этот метод хорошо работает с моим другом регулярное выражение, но еще не тогда, когда у меня есть $ 1 или \ 1 в замене ... вот что я получить :

final:\1\ee\ 

PS: вы ответили на первоначальный вопрос, следует ли открыть другое сообщение?

+1

Что такое допустимый первый символ, что-нибудь ? – sln

+0

Все утверждения действуют в текущем положении. Они смотрят вперед или назад. Поскольку '^' соответствует, текущая позиция равна 0, BOS, перед этим ничего нет. – sln

+0

'Этот метод хорошо работает с моим другим регулярным выражением, но еще нет, когда у меня есть $ 1 или \ 1 в replace'. Регулярное выражение просто заменяет то, что находится в' $ r'. Я думаю, вам нужно сделать еще один шаг, используя форму оценки 's /// e' (см. _perlre_ docs) для замены. Регулярное выражение будет выглядеть как '$ test = ~ s/$ p/$ r/e;'. – sln

ответ

1
^(\S)e$ 

Попробуйте this.Replace by $1 [ee]. См. Демонстрационный ролик.

https://regex101.com/r/hR7tH4/28

+0

почему downvoted ????????? – vks

+0

Несовершеннолетние здесь downvoting. +1 лучший ответ! – sln

+0

@sln thanx получил 2 downvotes сейчас: I – vks

1

Вы можете использовать следующее регулярное выражение, которое совпадает 2 символа, а затем вы можете заменить его $1\[$2$2\]:

^([a-zA-Z])([a-zA-Z])$ 

Демо:

$my_string =~ s/^([a-zA-Z])([a-zA-Z])$/$1[$2$2]/; 

См демонстрационная https://regex101.com/r/iD9oN4/1

+0

Вы забыли первую группу захвата во втором фрагменте кода. Кроме того, вам не нужно использовать скобки с обратным слэшем в RHS подстановки, и OP только хотел совместить строки, заканчивающиеся на 'e', а не строки, заканчивающиеся на любую букву. – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot Спасибо, я просто дал общее решение! – Kasramvd

1

Почему ты не используя группу захвата для замены?

`s/^([c|d|j|l|m|n|s|t])e$/\1 [ee]/g` 

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

Вот еще один вариант в зависимости от того, что вы ищете. Он будет соответствовать двухсимвольной строке, состоящей из одного символа a-z, за которым следует одна 'e' на собственной строке с возможными пробелами до или после.Он заменит это будет один символ аза а затем '[й]

`s/^\s*([a-z])e\s*$/\1 [ee]/` 
+0

Вам нужно объяснить, почему вы забрасываете, если хотите, чтобы люди вам помогли. – gymbrall

+0

Первое регулярное выражение действительно не нуждается в этих чередованиях в классе. Или подразумевается в классах. Второе регулярное выражение является хорошим обобщенным, позволяющим форматировать. +1. – sln

+0

'[a | b]' соответствует 'a',' b' и вертикальная полоса; вы должны использовать '[ab]', если вы не хотите сопоставлять литерал '' 's. Кроме того, [вы должны использовать '$ 1' вместо' \ 1'] (http://perldoc.perl.org/perlre.html#Warning-on-\1-Instead-of-$1). – ThisSuitIsBlackNot

1

Я хотел бы сделать что-то вроде этого

$word =~ s/^(\w{1})(e)$/$1$2e/; 
+0

или упрощен до $ word = ~ s/^ (\ w [e]) $/$ 1e /; –

+1

Здравствуйте, '\ w {1})' == '\ w'. И, действительно, нет необходимости захватывать _e_, ее константу. – sln

+0

да, поэтому я упростил это. –

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