siguiendo la idea de Mijoja, y aprovechando los problemas expuestos por JasonS, tuve esta idea; Lo revisé un poco, pero no estoy seguro de mí mismo, por lo que una verificación realizada por alguien más experto que yo en js regex sería genial :)
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)
mi salida personal:
Fa[match] ball bi[match] bal[match] [match]ama
El principio es llamar checker
en cada punto de la cadena entre dos caracteres, siempre que esa posición sea el punto de partida de:
--- cualquier subcadena del tamaño de lo que no se desea (aquí 'ba'
, por lo tanto ..
) (si se conoce ese tamaño; de lo contrario, quizás sea más difícil de hacer)
--- --- o más pequeño que eso si es el comienzo de la cadena: ^.?
y, después de esto,
--- lo que se debe buscar realmente (aquí 'll'
).
En cada llamada de checker
, habrá una prueba para verificar si el valor anterior ll
no es el que no queremos ( !== 'ba'
); si ese es el caso, llamamos a otra función, y tendrá que ser esta ( doer
) la que hará los cambios en str, si el propósito es este, o más genéricamente, ingresará los datos necesarios para procesar manualmente los resultados del escaneo de str
.
aquí cambiamos la cadena por lo que necesitábamos mantener un rastro de la diferencia de longitud para compensar las ubicaciones dadas por replace
, todas calculadas str
, que en sí mismas nunca cambian.
Como las cadenas primitivas son inmutables, podríamos haber usado la variable str
para almacenar el resultado de toda la operación, pero pensé que el ejemplo, ya complicado por los reemplazos, sería más claro con otra variable ( str_done
).
Supongo que, en términos de rendimiento, debe ser bastante duro: todos esos reemplazos inútiles de '' en '', this str.length-1
veces, más el reemplazo manual por hacedor, lo que significa una gran cantidad de cortes ... probablemente en este caso específico anterior que podría agrupar, cortando la cuerda solo una vez en pedazos alrededor de donde queremos insertarla [match]
e .join()
ingiriéndola consigo [match]
misma.
La otra cosa es que no sé cómo manejaría casos más complejos, es decir, valores complejos para la falsa mirada atrás ... la longitud es quizás la información más problemática para obtener.
y, en checker
caso de múltiples posibilidades de valores no deseados para $ atrás, tendremos que hacer una prueba con otra expresión regular (lo mejor es almacenar en caché (crear) en el exterior checker
, para evitar que se cree el mismo objeto de expresión regular) en cada llamada para checker
) saber si es o no lo que buscamos evitar.
espero haber sido claro; si no, no lo dudes, lo intentaré mejor. :)