Compruebe si una cadena contiene una subcadena

113

¿Cómo puedo comprobar si una determinada cadena contiene una determinada subcadena, utilizando Perl?

Más específicamente, quiero ver si s1.domain.comestá presente en la variable de cadena dada.

Pescado Belgin
fuente

Respuestas:

231

Para saber si una cadena contiene una subcadena, puede usar la indexfunción:

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

Devolverá la posición de la primera aparición de $substrin $str, o -1 si no se encuentra la subcadena.

Eugene Yarmash
fuente
6
Esta forma es especialmente preferible, cuando está buscando usando una variable; de ​​esta manera, no tendrá que usar caracteres de doble escape (en esta cadena de variables), que son especiales para expresiones regulares (como :).
evgeny9
57

Otra posibilidad es usar expresiones regulares, que es por lo que Perl es famoso:

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

Las barras invertidas son necesarias porque .puede coincidir con cualquier carácter. Puede evitar esto utilizando los operadores \Qy \E.

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

O puede hacer lo que eugene y dijo y usar la función de índice . Solo una advertencia: el índice devuelve un -1cuando no puede encontrar una coincidencia en lugar de un undefo 0.

Por tanto, esto es un error:

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

Esto será incorrecto si s1.domain.comestá al principio de su cadena. Personalmente, me han quemado con esto más de una vez.

David W.
fuente
¿Supongo que index()es más rápido que las expresiones regulares en el caso simple?
G. Cito
1
Un intento de respuesta Perl a una pregunta sobre la eliminación de subcadenas - Yo no se puede comparar la velocidad, pero =~, index(), ~~y match::simpletodo parecía un poco awk-WARD ...: - \
G. Cito
También debe asegurarse de que las cadenas que está comparando no distingan entre mayúsculas y minúsculas. S1.DOMAIN.COM no funcionará para la subcadena. Pero si hace lc ($ givendomain) y luego lo compara con "s1.domain.com", entonces funcionará. Además, la subcadena no es necesariamente el enfoque correcto; consulte mi nota anterior a la respuesta de eugene y
BlueChips23
@David W. De alguna manera no puedo domain.comigualar subdomain.domain.comusando el REGEX anterior, ¿alguna idea?
avrono
14

Ejemplo de subcadena que no distingue entre mayúsculas y minúsculas

Esta es una extensión de la respuesta de Eugene, que convierte las cadenas a minúsculas antes de verificar la subcadena:

if (index(lc($str), lc($substr)) != -1) {
    print "$str contains $substr\n";
} 
James Oravec
fuente
1
Tenga en cuenta que fcse recomienda lcpara las comparaciones que no distinguen entre mayúsculas y minúsculas.
melpomene