#regex #perl
#регулярное выражение #perl
Вопрос:
Я использую это регулярное выражение в Perl для сопоставления и замены следующих выражений:
_HI2_
_HI_2
HI2_
-
_HI_2
if ($subject =~ m/_?HI2?_?|HI2?_?/) { # Successful match } else { # Match attempt failed }
Я также хочу сделать это, хотя:
The text is: ABCDEMAFGHIJ
Это последовательность HI
там, но ее следует игнорировать, потому что, если вы посмотрите налево, вы увидите, что эта строка начинается с The text is:
.
The text is: ABCDEHI2FGHI
Как и выше, здесь две последовательности HI
.
Как я могу встроить в это регулярное выражение совпадение и игнорировать его из-за префикса строки?
Ответ №1:
Почему бы просто не сопоставить дважды? Если $subject не соответствует /^тексту:/ , запустите замену ..
Комментарии:
1. Просто используйте if(){}else{} . Предлагаю вам попробовать что-нибудь прочитать.. может быть, «современный perl»? Это бесплатно в формате PDF здесь: onyxneon.com/books/modern_perl
Ответ №2:
Попробуйте это регулярное выражение:
/^(?!The text is:).*(?:_?HI2?_?|HI2?_?)/
Или используйте два совпадения, например:
if($subject !~ /^This text is:/i amp;amp; $subject =~ /_?HI2?_?|HI2?_?/)
Комментарии:
1. используя пример 1: AAA_HI2_BBB_CCC <— Этот, кажется, единственный, который распознается, и он также распознает AAA_ перед HI2_ AAA_HI_2_BBB_CCC Текст: ABCDEMAFGHIJ Текст: ABCDEHI2FGHI
Ответ №3:
Я только что обнаружил этот замечательный ресурс здесь и раздел о Perl.
Вы можете найти там детали (*SKIP)(*F)
конструкции, которая поразит вас; вы описали проблему как однострочную:
cat > test.txt <<EOF
_HI2_
_HI_2xxxHI_2
The text is: ABCDEMAFGHIJ
HI2_
The text is: ABCDEHI2FGHI
_HI_2
EOF
perl -ne '/^The text is:.*$(*SKIP)(*F)|. / amp;amp; s/_?HI_?2?_?/HAPPY/; print' test.txt
# or
perl -ne 's/(^The text is:.*$)(*SKIP)(*F)|_?HI_?2?_?/HAPPY/g; print' test.txt
Я вновь обрел любовь и уважение к Perl; Я предпочитаю Sed, но теперь я знаю, как пропускать строки (читай: оставлять без изменений) в Perl, я буду меньше колебаться
Ответ №4:
Попробуйте указать, что это начало строки с «^», игнорируйте пробелы, если это, по вашему мнению, необходимо (я всегда стараюсь это делать). Также вы могли бы пометить конец строки символом «$»
if ($subject =~ m/^s*_?HI2?_?|HI2?_?/) {
# Successful match
} else {
# Match attempt failed
}
Ответ №5:
Не самый элегантный метод, но простой для понимания (TIMTOWTDI 🙂
#!/usr/bin/perl
use strict;
use warnings;
my @text = ("ABCDEHI2FGHI", "The text is: ABCDEHI2FGHI");
for (@text) {
my $new = my_replace($_); # do the replacement
print "$newn"; # print result
}
sub my_replace {
my ($text) = @_;
return $text if ($text =~ m/The text is:/); # return if prefixed / no replacement
$text =~ s/(_?HI2?_?|HI2?_?)/__replacement__/g; # do replace (give a replacement string here)
return $text; # return result of replacement
}
В противном случае вы можете использовать «отрицательный взгляд назад«.
Ответ №6:
/(?<!^The text is.*)(_?HI2?_?|HI2?_?)/
Комментарии:
1. Ссылки могут быть только фиксированной длины
2. хммм, строки с приветом в начале и «Текст есть» в них, похоже, все еще подбираются?
3. было бы лучше просто позволить perl-коду делать это?
if ($subject =~ m/The text is/) { # ignore the line, move onto the next line? -- what would the perl code be to do that? } else { # Match attempt failed }