Come ignorare gli spazi in una stringa del soggetto di un'espressione regolare?


107

Esiste un modo semplice per ignorare lo spazio bianco in una stringa di destinazione durante la ricerca di corrispondenze utilizzando un modello di espressione regolare? Ad esempio, se la mia ricerca è per "gatti", vorrei che "c ats" o "ca ts" corrispondessero. Non posso eliminare lo spazio bianco in anticipo perché ho bisogno di trovare l'indice di inizio e fine della corrispondenza (inclusi eventuali spazi) per evidenziare quella corrispondenza e gli spazi devono essere presenti per scopi di formattazione.

Risposte:


124

Puoi inserire caratteri di spazio bianco opzionali \s*tra ogni altro carattere nella tua regex. Sebbene scontato, diventerà un po 'lungo.

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


Grazie, sembra che questa sia la strada da percorrere. Ma mi sono appena reso conto che voglio solo i caratteri di spazio bianco opzionali se seguono una nuova riga. Quindi, ad esempio, "c \ n ats" o "ca \ n ts" dovrebbero corrispondere. Ma non vorrei che "c ats" corrispondesse se non c'è una nuova riga. Qualche idea su come potrebbe essere fatto?
Steven

@Steven, guarda come ho fatto di seguito, puoi adattare facilmente la mia soluzione a casi così specifici.
Bob

@chris penso, questa regex è così rigida solo per i gatti, può anche essere scritta per qualsiasi ricerca di lettere come questa: ^([a-z]\s*)+$
Sandeep Kaur

9

Indirizzando il commento di Steven alla risposta di Sam Dufel

Grazie, sembra che questa sia la strada da percorrere. Ma mi sono appena reso conto che voglio solo i caratteri di spazio bianco opzionali se seguono una nuova riga. Quindi, ad esempio, "c \ n ats" o "ca \ n ts" dovrebbero corrispondere. Ma non vorrei che "c ats" corrispondesse se non c'è una nuova riga. Qualche idea su come potrebbe essere fatto?

Questo dovrebbe fare il trucco:

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

Vedi questa pagina per tutte le diverse varianti di "gatti" che questo corrisponde.

Puoi anche risolvere questo problema usando i condizionali , ma non sono supportati nella versione javascript di regex.


3
Quindi molto brutto. Deve esserci un modo migliore.
james.garriss

Potresti renderlo più leggibile nella sintassi JS (anche se la tecnica funzionerebbe in altre lingue) con:new RegExp('cats'.split('').join('(?:\n\s*)?'))
brianary

7

Sebbene la risposta accettata sia tecnicamente corretta, un approccio più pratico, se possibile, è semplicemente rimuovere gli spazi bianchi sia dall'espressione regolare che dalla stringa di ricerca.

Se desideri cercare "i miei gatti", invece di:

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

Basta fare:

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

Avvertenza: non puoi automatizzare questa operazione sull'espressione regolare semplicemente sostituendo tutti gli spazi con stringhe vuote perché potrebbero verificarsi in una negazione o altrimenti rendere la tua espressione regolare non valida.


5

Puoi inserire \s*ogni carattere nella stringa di ricerca, quindi se stai cercando gatto lo userestic\s*a\s*t\s*s\s*s

È lungo ma potresti costruire la stringa in modo dinamico, ovviamente.

Puoi vederlo funzionare qui: http://www.rubular.com/r/zzWwvppSpE


3

Se vuoi solo consentire gli spazi, allora

\bc *a *t *s\b

dovrebbe farlo. Per consentire anche le schede, utilizzare

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

Rimuovi le \bancore se vuoi trovare anche catsall'interno di parole come bobcatso catsup.


1

Questo approccio può essere utilizzato per automatizzare (la seguente soluzione esemplare è in Python, sebbene ovviamente possa essere trasferita in qualsiasi linguaggio):

puoi rimuovere lo spazio bianco in anticipo E salvare le posizioni dei caratteri non di spazio bianco in modo da poterli utilizzare in seguito per scoprire le posizioni del limite della stringa corrispondente nella stringa originale come segue:

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'

Se vuoi andare oltre puoi costruire l'oggetto match e restituirlo invece, quindi l'uso di questo helper sarà più comodo.

E le prestazioni di questa funzione possono ovviamente essere ottimizzate, questo esempio serve solo a mostrare il percorso verso una soluzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.