Saya ingin menggunakan fungsi .replace untuk mengganti beberapa string.
Saat ini saya punya
string.replace("condition1", "")
tetapi ingin memiliki sesuatu seperti
string.replace("condition1", "").replace("condition2", "text")
meskipun itu tidak terasa seperti sintaks yang baik
apa cara yang tepat untuk melakukan ini? seperti bagaimana di grep / regex yang dapat Anda lakukan \1
dan \2
untuk mengganti bidang ke string pencarian tertentu
Jawaban:
Berikut adalah contoh singkat yang harus dilakukan dengan ekspresi reguler:
Sebagai contoh:
sumber
"spamham sha".replace("spam", "eggs").replace("sha","md5")
menjadi"eggmd5m md5"
bukan"eggsham md5"
Anda bisa membuat fungsi looping kecil yang menyenangkan.
di mana
text
string lengkap dandic
kamus - setiap definisi adalah string yang akan menggantikan kecocokan dengan istilah tersebut.Catatan : dalam Python 3,
iteritems()
telah diganti denganitems()
Hati-hati: kamus Python tidak memiliki urutan yang dapat diandalkan untuk iterasi. Solusi ini hanya menyelesaikan masalah Anda jika:
Misalnya:
Output yang mungkin # 1:
Output yang mungkin # 2
Salah satu perbaikan yang mungkin adalah dengan menggunakan OrderedDict.
Keluaran:
Hati-hati # 2: Tidak efisien jika
text
string Anda terlalu besar atau ada banyak pasangan di kamus.sumber
OrderedDict
- atau daftar 2-tupel.Kenapa tidak ada satu solusi seperti ini?
sumber
Berikut adalah varian dari solusi pertama menggunakan pengurangan, jika Anda suka menjadi fungsional. :)
Martineau versi yang lebih baik:
sumber
repls
urutan tupel dan melakukaniteritems()
panggilan. yaiturepls = ('hello', 'goodbye'), ('world', 'earth')
danreduce(lambda a, kv: a.replace(*kv), repls, s)
. Akan juga bekerja tidak berubah dalam Python 3.reduce
dihapus .reduce
masih ada, namun itu dibuat menjadi bagian darifunctools
modul (lihat dokumen ) di Python 3, jadi ketika saya mengatakan tidak berubah, saya maksudkan kode yang sama dapat dijalankan — walaupun diakui itu akan mengharuskan yangreduce
telahimport
diedit jika perlu karena tidak lagi built-in.Ini hanyalah rekap singkat dari jawaban bagus FJ dan MiniQuark. Yang Anda butuhkan untuk mencapai beberapa penggantian string simultan adalah fungsi berikut:
Pemakaian:
Jika mau, Anda dapat membuat fungsi pengganti khusus Anda sendiri mulai dari yang lebih sederhana ini.
sumber
rep_dict = {"but": "mut", "mutton": "lamb"}
string dengan kode Anda, tetapi akan memberikan jika penggantian dirantai, satu demi satu."button"
"mutton"
"lamb"
Do you prefer cafe? No, I prefer cafe.
, yang tidak diinginkan sama sekali.Saya membangun ini berdasarkan jawaban luar biasa FJ:
Penggunaan satu tembakan:
Perhatikan bahwa karena penggantian dilakukan hanya dalam satu pass, "café" berubah menjadi "tea", tetapi itu tidak berubah kembali menjadi "café".
Jika Anda perlu melakukan penggantian yang sama berkali-kali, Anda dapat membuat fungsi penggantian dengan mudah:
Perbaikan:
Nikmati! :-)
sumber
pattern.sub
mengharapkan fungsi hanya dengan satu parameter (teks untuk menggantikan), sehingga fungsi harus memiliki akses kereplace_dict
.re.M
memungkinkan penggantian Multiline (dijelaskan dengan baik dalam dokumen: docs.python.org/2/library/re.html#re.M ).Saya ingin mengusulkan penggunaan template string. Cukup tempatkan string yang akan diganti dalam kamus dan semua sudah diatur! Contoh dari docs.python.org
sumber
substitute
memunculkan pengecualian, jadi berhati-hatilah saat mendapatkan templat dari pengguna.Dalam kasus saya, saya perlu mengganti kunci unik dengan nama, jadi saya memikirkannya:
sumber
i
dengans
Anda akan mendapatkan perilaku aneh.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
Kemudian jika Anda berhati-hati untuk memesan pasangan array Anda, Anda dapat memastikan Anda tidak mengganti () secara rekursif.Mulai
Python 3.8
, dan pengenalan ekspresi penugasan (PEP 572) (:=
operator), kami dapat menerapkan penggantian dalam pemahaman daftar:sumber
['The quick red fox jumps over the lazy dog', 'The quick red fox jumps over the quick dog']
. Tetapi ekspresi penugasan (text := text.replace
) juga secara iteratif membangun versi barutext
dengan memutasikannya. Setelah pemahaman daftar, Anda bisa menggunakantext
variabel yang berisi teks yang dimodifikasi.text
sebagai satu-liner, Anda juga dapat menggunakan[text := text.replace(a, b) for a, b in replacements][-1]
(perhatikan[-1]
), yang mengekstrak elemen terakhir dari pemahaman daftar; yaitu versi terakhir daritext
.Di sini $ 0,02 saya. Ini didasarkan pada jawaban Andrew Clark, hanya sedikit lebih jelas, dan itu juga mencakup kasus ketika string untuk menggantikan adalah substring dari string lain untuk mengganti (string yang lebih lama menang)
Dalam inti ini , jangan ragu untuk memodifikasinya jika Anda memiliki proposal.
sumber
Saya membutuhkan solusi di mana string yang akan diganti dapat berupa ekspresi reguler, misalnya untuk membantu dalam menormalkan teks yang panjang dengan mengganti beberapa karakter spasi putih dengan yang tunggal. Membangun rangkaian jawaban dari orang lain, termasuk MiniQuark dan mmj, inilah yang saya temukan:
Ini berfungsi untuk contoh yang diberikan dalam jawaban lain, misalnya:
Hal utama bagi saya adalah Anda dapat menggunakan ekspresi reguler juga, misalnya untuk mengganti seluruh kata saja, atau untuk menormalkan ruang putih:
Jika Anda ingin menggunakan kunci kamus sebagai string normal, Anda dapat menghindarinya sebelum memanggil multiple_replace menggunakan mis. Fungsi ini:
Fungsi berikut dapat membantu menemukan ekspresi reguler yang salah di antara kunci kamus Anda (karena pesan kesalahan dari multiple_replace tidak terlalu memberi tahu):
Perhatikan bahwa itu tidak mengikat penggantian, melainkan menjalankannya secara bersamaan. Ini membuatnya lebih efisien tanpa membatasi apa yang dapat dilakukan. Untuk meniru efek rantai, Anda mungkin hanya perlu menambahkan lebih banyak pasangan pengganti-string dan memastikan urutan pasangan yang diharapkan:
sumber
Inilah contoh yang lebih efisien untuk string panjang dengan banyak penggantian kecil.
Intinya adalah menghindari banyak rangkaian string panjang. Kami memotong string sumber menjadi fragmen, mengganti beberapa fragmen saat kami membentuk daftar, dan kemudian menggabungkan semuanya kembali menjadi string.
sumber
Anda seharusnya tidak melakukannya dengan cara ini, tetapi saya merasa itu terlalu keren:
Sekarang,
answer
adalah hasil dari semua penggantian pada gilirannyasekali lagi, ini sangat hacky dan bukan sesuatu yang harus Anda gunakan secara teratur. Tapi senang mengetahui bahwa Anda dapat melakukan hal seperti ini jika perlu.
sumber
Saya juga berjuang dengan masalah ini. Dengan banyak pengganti, ekspresi reguler mengalami kesulitan, dan sekitar empat kali lebih lambat daripada perulangan
string.replace
(dalam kondisi percobaan saya).Anda harus benar-benar mencoba menggunakan pustaka Flashtext ( posting blog di sini , Github di sini ). Dalam kasus saya , itu sedikit lebih dari dua urutan besarnya lebih cepat, dari 1,8 detik menjadi 0,015 detik (ekspresi reguler mengambil 7,7 detik) untuk setiap dokumen.
Sangat mudah untuk menemukan contoh penggunaan di tautan di atas, tetapi ini adalah contoh yang berfungsi:
Perhatikan bahwa Flashtext membuat pergantian dalam satu pass (untuk menghindari a -> b dan b -> c menerjemahkan 'a' ke 'c'). Flashtext juga mencari seluruh kata (jadi 'is' tidak akan cocok dengan 'th is '). Ini berfungsi dengan baik jika target Anda adalah beberapa kata (mengganti 'Ini adalah' dengan 'Halo').
sumber
<p>
dengan/n
. Saya mencoba pendekatan Anda tetapi dengan tag flashtext sepertinya tidak menguraikannya?<
dan>
menandai akhir kata (tetapi disertakan dalam penggantian)?Saya merasa pertanyaan ini membutuhkan jawaban fungsi lambda rekursif single-line untuk kelengkapan, hanya karena. Jadi disana:
Pemakaian:
Catatan:
Catatan: Seperti halnya semua fungsi rekursif dalam python, kedalaman rekursi yang terlalu besar (yaitu kamus pengganti yang terlalu besar) akan menghasilkan kesalahan. Lihat misalnya di sini .
sumber
sys.getrecursionlimit()
adalah pasangan 1000, maks. gunakan loop atau sesuatu seperti itu, atau cobalah untuk menyederhanakan substitusi.Saya tidak tahu tentang kecepatan tapi ini perbaikan cepat hari kerja saya:
... tapi saya suka jawaban regex # 1 di atas. Catatan - jika satu nilai baru adalah substring dari yang lain maka operasi tidak komutatif.
sumber
Anda dapat menggunakan
pandas
pustaka danreplace
fungsi yang mendukung kedua kecocokan persis serta penggantian regex. Sebagai contoh:Dan teks yang dimodifikasi adalah:
Anda dapat menemukan contoh di sini . Perhatikan bahwa penggantian teks dilakukan dengan urutan mereka muncul dalam daftar
sumber
Untuk mengganti hanya satu karakter, gunakan
translate
danstr.maketrans
adalah favorit saya.tl; dr>
result_string = your_string.translate(str.maketrans(dict_mapping))
demo
sumber
Mulai dari jawaban berharga Andrew i mengembangkan skrip yang memuat kamus dari file dan menguraikan semua file pada folder yang dibuka untuk melakukan penggantian. Script memuat pemetaan dari file eksternal di mana Anda dapat mengatur pemisah. Saya seorang pemula tetapi saya menemukan skrip ini sangat berguna ketika melakukan banyak penggantian dalam beberapa file. Itu memuat kamus dengan lebih dari 1000 entri dalam hitungan detik. Itu tidak elegan tetapi berhasil untuk saya
sumber
ini solusi saya untuk masalah ini. Saya menggunakannya di chatbot untuk mengganti kata-kata yang berbeda sekaligus.
ini akan menjadi
The cat hunts the dog
sumber
Contoh lain: Daftar input
Output yang diinginkan adalah
Kode:
sumber
Atau hanya untuk retasan cepat:
sumber
Berikut cara lain melakukannya dengan kamus:
sumber