mengikuti ide Mijoja, dan menggambar dari masalah yang diungkapkan oleh JasonS, saya punya ide ini; saya memeriksa sedikit tetapi tidak yakin pada diri saya sendiri, jadi verifikasi oleh seseorang yang lebih ahli daripada saya di js regex akan sangat bagus :)
var re = /(?=(..|^.?)(ll))/g
, 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
}
, checker = function ($match, $behind, $after, $where, $str)
{
if ($behind !== "ba")
doer
(
$where + $behind.length
, $after
)
return $match
}
str.replace(re, checker)
console.log(str_done)
keluaran pribadi saya:
Fa[match] ball bi[match] bal[match] [match]ama
prinsipnya adalah memanggil checker
setiap titik dalam string di antara dua karakter mana pun, kapan pun posisi itu merupakan titik awal dari:
--- setiap substring dari ukuran apa yang tidak diinginkan (di sini 'ba'
, dengan demikian ..
) (jika ukuran itu diketahui; jika tidak, mungkin akan lebih sulit untuk dilakukan)
--- --- atau lebih kecil dari itu jika itu adalah awal dari string: ^.?
dan, setelah ini,
--- apa yang sebenarnya dicari (di sini 'll'
).
Pada setiap panggilan checker
, akan ada tes untuk memeriksa apakah nilai sebelumnya ll
bukan yang tidak kita inginkan ( !== 'ba'
); jika itu masalahnya, kita memanggil fungsi lain, dan itu harus yang ini ( doer
) yang akan membuat perubahan pada str, jika tujuannya adalah yang ini, atau lebih umum, yang akan memasukkan data yang diperlukan untuk diproses secara manual hasil pemindaian str
.
di sini kita mengubah string jadi kita perlu menyimpan jejak perbedaan panjang untuk mengimbangi lokasi yang diberikan replace
, semua dihitung str
, yang dengan sendirinya tidak pernah berubah.
karena string primitif tidak dapat diubah, kita dapat menggunakan variabel str
untuk menyimpan hasil dari seluruh operasi, tetapi saya pikir contoh, yang sudah diperumit oleh penggantian, akan lebih jelas dengan variabel lain ( str_done
).
Saya rasa dalam hal kinerja itu pasti cukup keras: semua penggantian tidak berguna dari '' ke '', this str.length-1
kali, ditambah di sini penggantian manual oleh pelaku, yang berarti banyak pemotongan ... mungkin dalam kasus khusus di atas yang bisa dikelompokkan, dengan memotong string hanya sekali-potong sekitar di mana kita ingin memasukkan [match]
dan .join()
ing dengan [match]
sendirinya.
hal lain adalah bahwa saya tidak tahu bagaimana cara menangani kasus yang lebih kompleks, yaitu, nilai kompleks untuk lookbehind palsu ... panjangnya mungkin data yang paling bermasalah untuk didapatkan.
dan, dalam checker
kasus beberapa kemungkinan nilai yang tidak diinginkan untuk $ di belakang, kita harus mengujinya dengan regex lain (untuk di-cache (dibuat) di luar checker
adalah yang terbaik, untuk menghindari objek regex yang sama dibuat pada setiap panggilan untuk checker
) untuk mengetahui apakah itu yang ingin kita hindari atau tidak.
harap saya sudah jelas; jika tidak, jangan ragu, saya akan mencoba lebih baik. :)