it-swarm.it

javascript regex - guarda dietro l'alternativa?

Ecco un regex che funziona bene nella maggior parte delle implementazioni di regex:

(?<!filename)\.js$

Questo corrisponde a .js per una stringa che termina con .js ad eccezione di nomefile.js

Javascript non ha regex lookbehind. Qualcuno è in grado di mettere insieme una regex alternativa che raggiunge lo stesso risultato e funziona in javascript?

Ecco alcuni pensieri, ma ha bisogno di funzioni di supporto. Speravo di riuscirci solo con un regex: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

132
daniel

^(?!filename).+\.js funziona per me

testato contro:

  • test.js match
  • partita blabla.js
  • nomefile.js nessuna corrispondenza

Una spiegazione corretta per questa regex può essere trovata in Espressione regolare per abbinare una stringa che non contiene una parola?

Guarda avanti è disponibile da versione 1.5 di javascript ed è supportato da tutti i principali browser

Aggiornato per corrispondere a nomefile2.js e 2filename.js ma non nomefile.js

(^(?!filename\.js$).).+\.js

EDIT: da ECMAScript 2018 in poi, le affermazioni lookbehind (anche illimitate) sono supportate in modo nativo .

Nelle versioni precedenti, puoi farlo:

^(?:(?!filename\.js$).)*\.js$

Questo fa esplicitamente ciò che l'espressione lookbehind sta facendo implicitamente: controlla ogni carattere della stringa se l'espressione lookbehind più la regex dopo che non corrisponderà, e solo allora consenti a quel carattere di corrispondere.

^                 # Start of string
(?:               # Try to match the following:
 (?!              # First assert that we can't match the following:
  filename\.js    # filename.js 
  $               # and end-of-string
 )                # End of negative lookahead
 .                # Match any character
)*                # Repeat as needed
\.js              # Match .js
$                 # End of string

Un'altra modifica:

Mi fa male dire (soprattutto da quando questa risposta è stata votata così tanto) che esiste un modo molto più semplice per raggiungere questo obiettivo. Non è necessario controllare il lookahead di ogni personaggio:

^(?!.*filename\.js$).*\.js$

funziona altrettanto bene:

^                 # Start of string
(?!               # Assert that we can't match the following:
 .*               # any string, 
  filename\.js    # followed by filename.js
  $               # and end-of-string
)                 # End of negative lookahead
.*                # Match any string
\.js              # Match .js
$                 # End of string
144
Tim Pietzcker

Supponiamo che tu voglia trovare tutto int non preceduto da unsigned:

Con supporto per look-behind negativo:

(?<!unsigned )int

Senza supporto per look-behind negativo:

((?!unsigned ).{9}|^.{0,8})int

Fondamentalmente l'idea è quella di prendere n caratteri precedenti ed escludere la corrispondenza con un aspetto negativo, ma anche abbinare i casi in cui non vi sono n caratteri precedenti. (dove n è la lunghezza del look-behind).

Quindi la regex in questione:

(?<!filename)\.js$

si tradurrebbe in:

((?!filename).{8}|^.{0,7})\.js$

Potrebbe essere necessario giocare con i gruppi di acquisizione per trovare il punto esatto della stringa che ti interessa o non vuoi sostituire una parte specifica con qualcos'altro.

23
Kamil Szot

Se puoi guardare avanti ma indietro, puoi prima invertire la stringa e poi fare uno sguardo. Un po 'più di lavoro dovrà essere fatto, ovviamente.

5
Albert Friend

Questa è una soluzione equivalente a risposta di Tim Pietzcker (vedi anche i commenti della stessa risposta):

^(?!.*filename\.js$).*\.js$

Significa, abbina *.js tranne *filename.js.

Per arrivare a questa soluzione, è possibile verificare quali pattern esclude il lookbehind negativo, quindi escludere esattamente questi pattern con un lookahead negativo.

1
weibeld