seguindo a idéia do Mijoja e tirando dos problemas expostos pelo JasonS, eu tive essa idéia; Eu verifiquei um pouco, mas não tenho certeza de mim mesmo, então uma verificação por alguém mais experiente do que eu em js regex seria ótimo :)
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)
minha saída pessoal:
Fa[match] ball bi[match] bal[match] [match]ama
o princípio é chamar checkerem cada ponto da cadeia entre dois caracteres, sempre que essa posição for o ponto inicial de:
--- qualquer substring do tamanho do que não é desejado (aqui 'ba', portanto ..) (se esse tamanho for conhecido; caso contrário, talvez seja mais difícil fazer isso)
--- --- ou menor que isso, se for o começo da string: ^.?
e, depois disso,
--- o que deve ser realmente procurado (aqui 'll').
A cada chamada de checker, haverá um teste para verificar se o valor anterior llnão é o que não queremos ( !== 'ba'); se for esse o caso, chamamos outra função, e terá que ser essa ( doer) que fará as alterações em str, se o objetivo for esse, ou mais genericamente, que entrará os dados necessários para processar manualmente os resultados da digitalização de str.
aqui, alteramos a sequência, de modo que precisamos manter um rastro da diferença de comprimento para compensar os locais dados por replace, todos calculados str, os quais nunca mudam.
Como as seqüências primitivas são imutáveis, poderíamos ter usado a variável strpara armazenar o resultado de toda a operação, mas pensei que o exemplo, já complicado pelas substituições, seria mais claro com outra variável ( str_done).
Eu acho que, em termos de desempenho, deve ser bem duro: todas essas substituições inúteis de '' into '', this str.length-1tempos, mais aqui a substituição manual por doer, o que significa muito fatiamento ... provavelmente neste caso específico acima ser agrupados, cortando a corda apenas uma vez em pedaços ao redor de onde queremos inseri -la [match]e inserindo - .join()a em [match]si mesma.
a outra coisa é que eu não sei como ele lidaria com casos mais complexos, ou seja, valores complexos para o lookback por trás ... o comprimento talvez seja o dado mais problemático a ser obtido.
e, no checkercaso de várias possibilidades de valores indesejados para $ behind, teremos que fazer um teste com mais uma regex (ser armazenado em cache (criado) fora checkeré o melhor, para evitar o mesmo objeto de regex a ser criado a cada pedido checker) para saber se é ou não o que procuramos evitar.
espero ter sido claro; se não, não hesite, tentarei melhor. :)