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 checker
em 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 ll
nã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 str
para 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-1
tempos, 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 checker
caso 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. :)