web-dev-qa-db-fra.com

Comment ignorer les espaces dans une chaîne de sujet d'expression régulière?

Existe-t-il un moyen simple d'ignorer les espaces dans une chaîne cible lors de la recherche de correspondances à l'aide d'un modèle d'expression régulière? Par exemple, si ma recherche porte sur "chats", je voudrais que "c ats" ou "ca ts" corresponde. Je ne peux pas supprimer les espaces au préalable car je dois trouver les index de début et de fin de la correspondance (y compris les espaces) pour mettre en surbrillance cette correspondance et tous les espaces doivent être présents à des fins de formatage. 

85
Steven

Vous pouvez insérer des caractères d'espacement optionnels \s* entre tous les autres caractères de votre expression régulière. Bien que accordé, cela deviendra un peu long.

/cats/ -> /c\s*a\s*t\s*s/

97
Sam Dufel

Répondre au commentaire de Steven sur la réponse de Sam Dufel

Merci, on dirait que c'est la voie à suivre. Mais je viens de me rendre compte que je ne veux les caractères d’espace optionnels qu’ils suivent une nouvelle ligne. Ainsi, par exemple, "c\n ats" ou "ca\n ts" devrait correspondre. Mais ne voudrions pas que les "c ats" correspondent s'il n'y a pas de nouvelle ligne. Des idées sur la façon dont cela pourrait être fait?

Cela devrait faire l'affaire:

/c(?:\n\s*)?a(?:\n\s*)?t(?:\n\s*)?s/

Voir cette page pour toutes les variantes de "chats" auxquelles cela correspond.

Vous pouvez également résoudre ce problème en utilisant conditionals , mais ils ne sont pas pris en charge dans la version javascript de regex.

6
Aurimas

Si vous voulez seulement laisser des espaces, alors

\bc *a *t *s\b

devrait le faire. Pour autoriser également les onglets, utilisez

\bc[ \t]*a[ \t]*t[ \t]*s\b

Supprimez les ancres \b si vous souhaitez également trouver cats dans des mots tels que bobcats ou catsup.

3
Tim Pietzcker

Vous pouvez mettre \s* entre chaque caractère de votre chaîne de recherche, donc si vous cherchez un chat, vous utiliseriez c\s*a\s*t\s*s\s*s

C'est long mais vous pouvez bien sûr construire la chaîne de manière dynamique.

Vous pouvez le voir fonctionner ici: http://www.rubular.com/r/zzWwvppSpE

3
Kludge

Bien que la réponse acceptée soit techniquement correcte, une approche plus pratique, si possible, consiste simplement à supprimer les espaces blancs de l'expression régulière et de la chaîne de recherche.

Si vous voulez rechercher "mes chats", au lieu de:

myString.match(/m\s*y\s*c\s*a\*st\s*s\s*/g)

Il suffit de faire:

myString.replace(/\s*/g,"").match(/mycats/g)

Avertissement: vous ne pouvez pas automatiser cette opération sur l'expression régulière en remplaçant simplement tous les espaces par des chaînes vides, car elles peuvent apparaître lors d'une négation ou rendre votre expression régulière non valide.

1
Konrad Höffner

Cette approche peut être utilisée pour automatiser this (La solution exemplaire suivante est en python, bien qu’elle puisse évidemment être portée dans n’importe quel langage):

vous pouvez supprimer au préalable les espaces ET enregistrer les positions des caractères autres que des espaces afin de pouvoir les utiliser ultérieurement pour connaître les positions des limites de chaîne correspondantes dans la chaîne d'origine, comme suit:

def regex_search_ignore_space(regex, string):
    no_spaces = ''
    char_positions = []

    for pos, char in enumerate(string):
        if re.match(r'\S', char):  # upper \S matches non-whitespace chars
            no_spaces += char
            char_positions.append(pos)

    match = re.search(regex, no_spaces)
    if not match:
        return match

    # match.start() and match.end() are indices of start and end
    # of the found string in the spaceless string
    # (as we have searched in it).
    start = char_positions[match.start()]  # in the original string
    end = char_positions[match.end()]  # in the original string
    matched_string = string[start:end]  # see

    # the match WITH spaces is returned.
    return matched_string

with_spaces = 'a li on and a cat'
print(regex_search_ignore_space('lion', with_spaces))
# prints 'li on'

Si vous voulez aller plus loin, vous pouvez construire l'objet match et le renvoyer à la place, de sorte que l'utilisation de cet assistant sera plus pratique.

Et les performances de cette fonction peuvent bien sûr également être optimisées, cet exemple n’est qu’à montrer le chemin qui mène à une solution.

0
Bob