Sprawdź, czy ciąg zawiera podciąg

113

Jak mogę sprawdzić, czy dany ciąg zawiera określony podciąg, używając Perla?

Dokładniej, chcę sprawdzić, czy s1.domain.comwystępuje w danej zmiennej ciągu.

Belgin Fish
źródło

Odpowiedzi:

232

Aby dowiedzieć się, czy ciąg zawiera podciąg, możesz użyć indexfunkcji:

if (index($str, $substr) != -1) {
    print "$str contains $substr\n";
} 

Zwróci pozycję pierwszego wystąpienia $substrin $strlub -1, jeśli podciąg nie zostanie znaleziony.

Eugene Yarmash
źródło
6
Ten sposób jest szczególnie preferowany, gdy szukasz przy użyciu zmiennej - w ten sposób nie będziesz musiał używać podwójnych znaków ucieczki (w tym ciągu zmiennej), które są specjalne dla wyrażeń regularnych (takich jak :).
evgeny9
57

Inną możliwością jest użycie wyrażeń regularnych, z czego słynie Perl:

if ($mystring =~ /s1\.domain\.com/) {
   print qq("$mystring" contains "s1.domain.com"\n);
}

Ukośniki odwrotne są potrzebne, ponieważ a .może pasować do dowolnego znaku. Możesz to obejść za pomocą operatorów \Qi \E.

my $substring = "s1.domain.com";
    if ($mystring =~ /\Q$substring\E/) {
   print qq("$mystring" contains "$substring"\n);
}

Lub możesz zrobić tak, jak powiedział eugene y i użyć funkcji indeksu . Tylko słowo ostrzeżenia: indeks zwraca a, -1gdy nie może znaleźć dopasowania zamiast undeflub 0.

Tak więc jest to błąd:

my $substring = "s1.domain.com";
if (not index($mystring, $substr)) {
    print qq("$mystring" doesn't contains "$substring"\n";
} 

Będzie źle, jeśli s1.domain.comznajduje się na początku twojego ciągu. Osobiście byłem tym palony więcej niż raz.

David W.
źródło
Przypuszczam, że index()jest szybszy niż wyrażenia regularne w prostym przypadku?
G. Cito,
1
Próba odpowiedzi na pytanie perla o usunięcie podciągi - Nie porównać szybkość, ale =~, index(), ~~i match::simplewszystko wydawało się nieco awk-ward ...: - \
G. Cito
Musisz również upewnić się, że porównywane ciągi nie uwzględniają wielkości liter. S1.DOMAIN.COM nie będzie działać dla podciągu. Ale jeśli lc ($ givendomain), a następnie porównasz to z „s1.domain.com”, to zadziała. Ponadto, podciąg niekoniecznie jest właściwym podejściem - zobacz moją notatkę powyżej dotyczącą odpowiedzi Eugene y
BlueChips 23
@David W. Jakoś nie mogę domain.comdopasować subdomain.domain.comużywając powyższego REGEX, jakieś pomysły?
avrono
14

Przykład podłańcucha bez rozróżniania wielkości liter

To jest rozszerzenie odpowiedzi Eugene'a, która konwertuje ciągi znaków na małe litery przed sprawdzeniem podłańcucha:

if (index(lc($str), lc($substr)) != -1) {
    print "$str contains $substr\n";
} 
James Oravec
źródło
1
Należy pamiętać, że fcjest to zalecane w lcprzypadku porównań bez uwzględniania wielkości liter.
melpomene