слідуючи ідеї Мійоха та виходячи з проблем, які викривав Джейсонс, у мене була така ідея; Я перевірив трохи, але не впевнений у собі, тому перевірка з боку когось більш експертного, ніж я, у 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
) знати, чи варто цього уникати чи ні.
сподіваюся, що я зрозумів; якщо не вагайтеся, я спробую краще. :)