слідуючи ідеї Мійоха та виходячи з проблем, які викривав Джейсонс, у мене була така ідея; Я перевірив трохи, але не впевнений у собі, тому перевірка з боку когось більш експертного, ніж я, у js regex була б чудовою :)
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)
мій особистий результат:
Fa[match] ball bi[match] bal[match] [match]ama
принцип полягає у виклику checkerв кожній точці рядка між будь-якими двома символами, коли ця позиція є початковою точкою:
--- будь-яка підрядка розміру того, що не потрібно (тут 'ba', таким чином ..) (якщо цей розмір відомий; інакше це може бути важче зробити)
--- --- або менше, ніж це, якщо це початок рядка: ^.?
і, слідуючи за цим,
--- що потрібно насправді шукати (тут 'll').
При кожному виклику checker, буде тест, щоб перевірити, чи не було раніше значення ll, яке ми не хочемо ( !== 'ba'); якщо це так, ми називаємо іншу функцію, і вона повинна бути саме цією ( doer), яка внесе зміни на str, якщо мета ця, або, більш загально, буде отримувати необхідні дані для ручної обробки результати сканування str.
тут ми змінюємо рядок, тому нам потрібно було слідкувати за різницею довжини, щоб компенсувати розташування, задані replace, усі розраховані на str, яка сама ніколи не змінюється.
Оскільки примітивні рядки незмінні, ми могли б використати змінну strдля зберігання результату всієї операції, але я вважав, що приклад, уже ускладнений заміною, буде зрозумілішим з іншою змінною ( str_done).
я здогадуюсь, що з точки зору виступів він повинен бути досить суворим: усі ці безглузді заміни '' на '', this str.length-1часи, плюс тут ручна заміна на doer, що означає багато нарізки ... напевно, у цьому конкретному вище випадку, що могло б будемо групуватися, розрізаючи струну лише один раз на шматочки навколо, куди ми хочемо вставити, [match]і .join()розгорнути її [match].
інша річ - це те, що я не знаю, як воно обробляло б більш складні випадки, тобто складні значення для підроблених поглядів позаду ... довжина, мабуть, найбільш проблемні дані.
і, у checkerвипадку, якщо у кількох можливостях небажаних значень за $ позаду, нам доведеться зробити тест на ньому з ще одним регексом (щоб бути кешованим (створеним) назовні checkerнайкраще, щоб уникнути того самого об'єкта, який буде створений регулярним виразом). під час кожного заклику checker) знати, чи варто цього уникати чи ні.
сподіваюся, що я зрозумів; якщо не вагайтеся, я спробую краще. :)