podążając za ideą Mijoja i czerpiąc z problemów ujawnionych przez JasonS, wpadłem na ten pomysł; trochę sprawdziłem, ale nie jestem pewien siebie, więc weryfikacja przez kogoś bardziej eksperta ode mnie w js regex byłaby świetna :)
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)
moje osobiste wyniki:
Fa[match] ball bi[match] bal[match] [match]ama
zasadą jest wywołanie checker
w każdym punkcie ciągu między dowolnymi dwoma znakami, ilekroć ta pozycja jest punktem początkowym:
--- dowolny fragment wielkości co nie jest pożądane (tutaj 'ba'
, w ten sposób ..
) (jeśli rozmiar jest znany, w przeciwnym razie musi to być trudniejsze do zrobienia chyba)
--- --- lub mniejsza, jeśli to początek ciągu: ^.?
a następnie
--- czego faktycznie należy szukać (tutaj 'll'
).
Przy każdym wywołaniu funkcji checker
będzie test sprawdzający, czy poprzednia wartość ll
nie jest tym, czego nie chcemy ( !== 'ba'
); jeśli tak jest, wywołujemy inną funkcję i będzie to ta ( doer
), która wprowadzi zmiany na str, jeśli celem jest ten lub bardziej ogólnie, wprowadzi dane niezbędne do ręcznego przetworzenia wyniki skanowania str
.
tutaj zmieniamy ciąg, więc musieliśmy zachować ślad różnicy długości, aby zrównoważyć lokalizacje podane przez replace
, wszystkie obliczone na podstawie str
, które same się nigdy nie zmieniają.
ponieważ ciągi pierwotne są niezmienne, moglibyśmy użyć zmiennej str
do przechowywania wyniku całej operacji, ale pomyślałem, że przykład, już skomplikowany przez zamiany, byłby bardziej przejrzysty z inną zmienną ( str_done
).
wydaje mi się, że jeśli chodzi o występy, to musi być dość surowe: wszystkie te bezsensowne zamiany this str.length-1
czasów `` na '' plus tutaj ręczna wymiana przez wykonawcę, co oznacza dużo krojenia ... prawdopodobnie w tym konkretnym przypadku, który mógłby być zgrupowane, przecinając sznurek tylko raz na kawałki wokół miejsca, w którym chcemy wstawić, [match]
i .join()
łącząc go ze [match]
sobą.
Inną rzeczą jest to, że nie wiem, jak poradziłby sobie z bardziej złożonymi przypadkami, to znaczy ze złożonymi wartościami dla fałszywego lookbehind ... długość jest prawdopodobnie najbardziej problematycznymi danymi do uzyskania.
a checker
w przypadku wielu możliwości niepotrzebnych wartości dla $ za nimi, będziemy musieli wykonać test z jeszcze innym wyrażeniem regularnym ( checker
najlepiej buforowanym (utworzonym) na zewnątrz , aby uniknąć tworzenia tego samego obiektu wyrażenia regularnego na każde wezwanie checker
), aby wiedzieć, czy jest to to, czego staramy się unikać.
mam nadzieję, że wyraziłem się jasno; jeśli nie, nie wahaj się, spróbuję lepiej. :)