regex javascript – guarda dietro un’alternativa?

Ecco una regex che funziona bene nella maggior parte delle implementazioni di espressioni regolari:

(?<!filename)\.js$ 

Questo corrisponde a .js per una stringa che termina con .js tranne per filename.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 aiuto. Speravo di raggiungerlo solo con una regex: http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

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

testato contro:

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

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

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

Aggiornato per abbinare filename2.js e 2filename.js ma non filename.js

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

MODIFICA: Da ECMAScript 2018 in poi, le ulteriori asserzioni (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 in modo implicito: controlla ciascun carattere della stringa se l’espressione lookbehind più la regex dopo di essa non corrisponde, e solo allora permetti a quel personaggio 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 addolora dire (soprattutto dal momento che questa risposta è stata svalutata così tanto) che c’è un modo molto più facile per raggiungere questo objective. Non è necessario controllare il lookahead in 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 

Supponiamo che tu voglia trovare tutti int non preceduti da unsigned :

Con il supporto per il look-back negativo:

 (?< !unsigned )int 

Senza supporto per il look-back negativo:

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

Fondamentalmente l'idea è di afferrare n caratteri precedenti ed escludere la corrispondenza con look-out negativo, ma anche i casi in cui non ci sono caratteri precedenti. (dove n è la lunghezza di guardare indietro).

Quindi la regex in questione:

 (?< !filename)\.js$ 

tradurrebbe in:

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

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

Se riesci a guardare avanti ma indietro, potresti invertire prima la stringa e poi fare un controllo. Occorrerà fare ancora un po ‘di lavoro, naturalmente.

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

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

Significa, corrisponde *.js tranne *filename.js .

Per arrivare a questa soluzione, è ansible verificare quali pattern escludono l’aspetto negativo dietro e quindi escludere esattamente questi pattern con un lookahead negativo.

Di seguito è riportato un positivo lookbehind alternativa JavaScript che mostra come catturare il cognome delle persone con “Michael” come loro nome.

1) Dato questo testo:

 const exampleText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?"; 

ottenere una serie di cognomi di persone di nome Michael. Il risultato dovrebbe essere: ["Jordan","Johnson","Green","Wood"]

2) Soluzione:

 function getMichaelLastName2(text) { return text .match(/(?:Michael )([AZ][az]+)/g) .map(person => person.slice(person.indexOf(' ')+1)); } // or even .map(person => person.slice(8)); // since we know the length of "Michael " 

3) Controllare la soluzione

 console.log(JSON.stringify( getMichaelLastName(exampleText) )); // ["Jordan","Johnson","Green","Wood"] 

Demo qui: http://codepen.io/PiotrBerebecki/pen/GjwRoo

Puoi anche provarlo eseguendo lo snippet qui sotto.

 const inputText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?"; function getMichaelLastName(text) { return text .match(/(?:Michael )([AZ][az]+)/g) .map(person => person.slice(8)); } console.log(JSON.stringify( getMichaelLastName(inputText) ));