ตามความคิดของ Mijoja และการวาดภาพจากปัญหาที่เปิดเผยโดย JasonS ฉันมีความคิดนี้; ฉันตรวจสอบนิดหน่อย แต่ฉันก็ไม่แน่ใจในตัวเองดังนั้นการยืนยันโดยใครบางคนที่มีความเชี่ยวชาญมากกว่าฉันใน 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
ครั้ง, และที่นี่การแทนที่ด้วยมือโดยผู้กระทำซึ่งหมายถึงการหั่นเป็นจำนวนมาก ... อาจเป็นในกรณีข้างต้นนี้ ถูกจัดกลุ่มโดยการตัดสตริงเพียงครั้งเดียวเป็นชิ้น ๆ ที่เราต้องการแทรก[match]
และ.join()
ไอเอ็นจีด้วย[match]
ตัวเอง
อีกอย่างคือฉันไม่รู้ว่ามันจะจัดการกับกรณีที่ซับซ้อนมากขึ้นได้อย่างไรนั่นคือค่าที่ซับซ้อนสำหรับลุคปลอม ๆ ... ความยาวอาจเป็นข้อมูลที่มีปัญหามากที่สุด
และchecker
ในกรณีที่มีความเป็นไปได้หลายอย่างของค่าที่ไม่ต้องการสำหรับ $ behind เราจะต้องทำการทดสอบกับ regex อื่น (ที่จะถูกแคช (สร้าง)) นอกที่checker
ดีที่สุดเพื่อหลีกเลี่ยงวัตถุ regex เดียวกันที่จะสร้าง ในแต่ละครั้งที่โทรหาchecker
) เพื่อทราบว่าเป็นสิ่งที่เราพยายามหลีกเลี่ยงหรือไม่
หวังว่าฉันจะชัดเจน; ถ้าไม่ลังเลฉันจะพยายามให้ดีขึ้น :)