seguendo l'idea di Mijoja e attingendo ai problemi esposti da JasonS, ho avuto questa idea; ho controllato un po 'ma non sono sicuro di me stesso, quindi una verifica da parte di qualcuno più esperto di me in js regex sarebbe ottima :)
var re = /(?=(..|^.?)(ll))/g
// matches empty string position
// whenever this position is followed by
// a string of length equal or inferior (in case of "^")
// to "lookbehind" value
// + actual value we would want to match
, str = "Fall ball bill balll llama"
, str_done = str
, len_difference = 0
, doer = function (where_in_str, to_replace)
{
str_done = str_done.slice(0, where_in_str + len_difference)
+ "[match]"
+ str_done.slice(where_in_str + len_difference + to_replace.length)
len_difference = str_done.length - str.length
/* if str smaller:
len_difference will be positive
else will be negative
*/
} /* the actual function that would do whatever we want to do
with the matches;
this above is only an example from Jason's */
/* function input of .replace(),
only there to test the value of $behind
and if negative, call doer() with interesting parameters */
, checker = function ($match, $behind, $after, $where, $str)
{
if ($behind !== "ba")
doer
(
$where + $behind.length
, $after
/* one will choose the interesting arguments
to give to the doer, it's only an example */
)
return $match // empty string anyhow, but well
}
str.replace(re, checker)
console.log(str_done)
la mia uscita personale:
Fa[match] ball bi[match] bal[match] [match]ama
il principio è chiamare checker
in ogni punto della stringa tra due caratteri qualsiasi, ogni volta che quella posizione è il punto iniziale di:
--- qualsiasi sottostringa della dimensione di ciò che non è voluto (qui 'ba'
, quindi ..
) (se tale dimensione è nota; altrimenti dovrebbe essere più difficile da fare forse)
--- --- o più piccolo di quello se è l'inizio della stringa: ^.?
e, in seguito,
--- cosa si deve effettivamente cercare (qui 'll'
).
Ad ogni chiamata di checker
, ci sarà un test per verificare se il valore precedente ll
non è quello che non vogliamo ( !== 'ba'
); in tal caso, chiamiamo un'altra funzione e dovrà essere questa ( doer
) che apporterà le modifiche su str, se lo scopo è questo, o più genericamente, che entrerà in input i dati necessari per l'elaborazione manuale i risultati della scansione di str
.
qui cambiamo la stringa, quindi abbiamo bisogno di tenere traccia della differenza di lunghezza per compensare le posizioni fornite da replace
, tutte calcolate su str
, che di per sé non cambiano mai.
poiché le stringhe primitive sono immutabili, avremmo potuto usare la variabile str
per memorizzare il risultato dell'intera operazione, ma ho pensato che l'esempio, già complicato dalle sostituzioni, sarebbe stato più chiaro con un'altra variabile ( str_done
).
Immagino che in termini di prestazioni debba essere piuttosto duro: tutte quelle inutili sostituzioni di '' in '', i this str.length-1
tempi, più qui la sostituzione manuale di doer, il che significa un sacco di tagli ... probabilmente in questo caso specifico sopra che potrebbe essere raggruppati, tagliando la stringa una sola volta in pezzi attorno a dove vogliamo inserirla [match]
e inserendola .join()
con [match]
sé.
l'altra cosa è che non so come gestirà casi più complessi, ovvero valori complessi per il falso lookbehind ... la lunghezza è forse il dato più problematico da ottenere.
e, in checker
caso di più possibilità di valori non desiderati per $ behind, dovremo fare un test su di esso con l'ennesima regex (essere memorizzati nella cache (creati) all'esterno checker
è la cosa migliore, per evitare che lo stesso oggetto regex venga creato ad ogni richiesta di checker
) sapere se è o meno ciò che cerchiamo di evitare.
spero di essere stato chiaro; se non esitare, proverò meglio. :)