Saya mencoba menghapus karakter tertentu dari sebuah string menggunakan Python. Ini adalah kode yang saya gunakan sekarang. Sayangnya, tampaknya tidak melakukan apa pun pada string.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
Bagaimana saya melakukan ini dengan benar?
String dalam Python bersifat immutable (tidak dapat diubah). Karena itu, efek dari line.replace(...)
hanya untuk membuat string baru, bukan mengubah string yang lama. Anda perlu rebind (menetapkan) ke line
agar variabel itu mengambil nilai baru, dengan karakter-karakter yang dihapus.
Juga, cara yang Anda lakukan akan menjadi agak lambat, secara relatif. Hal ini juga mungkin akan sedikit membingungkan bagi pythonator berpengalaman, yang akan melihat struktur bersarang ganda dan berpikir sejenak bahwa ada sesuatu yang lebih rumit yang sedang terjadi.
Mulai Python 2.6 dan versi Python 2.x yang lebih baru *, Anda dapat menggunakan str.translate
, (tetapi baca terus untuk perbedaan Python 3):
line = line.translate(None, '!@#$')
atau penggantian ekspresi reguler dengan re.sub
import re
line = re.sub('[!@#$]', '', line)
Karakter-karakter yang diapit oleh tanda kurung merupakan kelas karakter. Setiap karakter dalam line
yang berada dalam kelas tersebut diganti dengan parameter kedua untuk sub
: string kosong.
Dalam Python 3, string adalah Unicode. Anda harus menerjemahkannya sedikit berbeda. kevpie menyebutkan hal ini dalam komentar pada salah satu jawaban, dan itu dicatat dalam dokumentasi untuk str.translate
.
Ketika memanggil metode terjemahkan
dari string Unicode, Anda tidak dapat meneruskan parameter kedua yang kita gunakan di atas. Anda juga tidak bisa melewatkan None
sebagai parameter pertama, atau bahkan tabel terjemahan dari string.maketrans
. Sebagai gantinya, Anda mengoper kamus sebagai satu-satunya parameter. Kamus ini memetakan nilai ordinal karakter (yaitu hasil pemanggilan ord
pada karakter tersebut) ke nilai ordinal karakter yang harus menggantikannya, atau - yang berguna bagi kita-None
untuk menunjukkan bahwa karakter tersebut harus dihapus.
Jadi untuk melakukan tarian di atas dengan string Unicode, Anda akan memanggil sesuatu seperti
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
Di sini dict.fromkeys
dan map
digunakan untuk secara ringkas menghasilkan kamus yang berisi
{ord('!'): None, ord('@'): None, ...}
Bahkan lebih sederhana lagi, seperti yang dikatakan jawaban lain, buatlah kamus di tempat:
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
* untuk kompatibilitas dengan Python sebelumnya, Anda dapat membuat "null" tabel terjemahan untuk menggantikan None
:
import string
line = line.translate(string.maketrans('', ''), '!@#$')
Di sini string.maketrans
digunakan untuk membuat tabel terjemahan, yang hanya berupa string yang berisi karakter-karakter dengan nilai ordinal 0 sampai 255.
Saya hilang di sini, atau itu hanya hal berikut:
``python string = "ab1cd1ef" string.mengganti("1","")
cetak string
``
Memasukkannya ke dalam loop:
``puthon a = "!b@c#d$" b = "!@#$" untuk char b: a = a.replace(char",")
cetak
``
re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
>>> import re
>>> line = 'Q: Do I write ;/.??? No!!!'
>>> re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
'QDoIwriteNo'
Dalam [expressions reguler] (https://en.wikipedia.org/wiki/Regular_expression) (regex), |
adalah OR logis dan \
melarikan diri ruang dan karakter khusus yang mungkin benar-benar regex perintah. Sedangkan sub
berarti pengganti, dalam kasus ini dengan string kosong `''.
Untuk inverse persyaratan hanya memungkinkan karakter tertentu dalam sebuah string, anda dapat menggunakan ekspresi reguler dengan melengkapi operator [^ABCabc]
. Misalnya, untuk menghapus semuanya kecuali ascii huruf, angka, dan tanda hubung:
>>> import string
>>> import re
>>>
>>> phrase = ' There were "nine" (9) chick-peas in my pocket!!! '
>>> allow = string.letters + string.digits + '-'
>>> re.sub('[^%s]' % allow, '', phrase)
'Therewerenine9chick-peasinmypocket'
Dari python ekspresi reguler dokumentasi:
Karakter yang tidak berada dalam kisaran yang dapat dicocokkan dengan melengkapi set. Jika karakter pertama dari set
'^'
, semua karakter yang tidak di set akan dicocokkan. Misalnya,[^5]
akan cocok karakter apapun kecuali '5', dan[^^]
akan cocok dengan karakter apapun kecuali'^'
.^
tidak memiliki arti khusus jika itu bukan karakter pertama dalam set.
Penanya hampir memilikinya. Seperti kebanyakan hal dalam Python, jawabannya adalah lebih sederhana dari yang anda pikirkan.
>>> line = "H E?.LL!/;O:: "
>>> for char in ' ?.!/;:':
... line = line.replace(char,'')
...
>>> print line
HELLO
Anda don't harus melakukan nested if/untuk loop hal, tetapi anda perlu untuk memeriksa setiap karakter individual.
Saya terkejut bahwa tidak ada yang memiliki namun dianjurkan menggunakan pertamax filter fungsi.
import operator
import string # only for the example you could use a custom string
s = "1212edjaq"
Katakanlah kita ingin menyaring segala sesuatu yang isn't nomor. Menggunakan filter builtin metode "...setara dengan generator ekspresi (item untuk item di iterable fungsi if(item))" [Python 3 Builtins: Filter]
sList = list(s)
intsList = list(string.digits)
obj = filter(lambda x: operator.contains(intsList, x), sList)))
Di Python 3 ini kembali
>> <filter object @ hex>
Untuk mendapatkan cetak string,
nums = "".join(list(obj))
print(nums)
>> "1212"
Saya tidak yakin bagaimana filter jajaran dalam hal efisiensi, tetapi itu adalah hal yang baik untuk mengetahui bagaimana untuk menggunakan ketika melakukan daftar pemahaman dan semacamnya.
UPDATE
Logikanya, karena filter ini berfungsi anda juga bisa menggunakan daftar pemahaman dan dari apa yang saya baca hal ini seharusnya menjadi lebih efisien karena lambdas adalah wall street manajer hedge fund dari fungsi pemrograman dunia. Kelebihan lainnya adalah bahwa ini adalah satu-kapal yang tidak memerlukan impor. Misalnya, menggunakan string yang sama 's' yang didefinisikan di atas,
num = "".join([i for i in s if i.isdigit()])
Yang's ini. Kembali akan sebuah string dari semua karakter yang ada angka dalam string asli.
Jika anda memiliki daftar khusus yang dapat diterima/tidak dapat diterima karakter anda hanya perlu menyesuaikan 'jika' bagian dari daftar pemahaman.
target_chars = "".join([i for i in s if i in some_list])
atau sebagai alternatif,
target_chars = "".join([i for i in s if i not in some_list])
Menggunakan filter
, anda'a hanya perlu satu baris
line = filter(lambda char: char not in " ?.!/;:", line)
Ini memperlakukan string sebagai iterable dan memeriksa setiap karakter jika lambda
mengembalikan True
:
membantu(filter) Bantuan pada built-in fungsi filter dalam modul builtin:
filter(...) filter(fungsi atau Tidak, urutan) -> list, tuple, atau string
Return item-item dari urutan yang function(item) adalah benar. Jika fungsi ini Tidak ada, mengembalikan barang-barang yang benar. Jika urutan adalah sebuah tuple atau string, kembali jenis yang sama, yang lain kembali daftar.
Berikut ini's beberapa cara yang mungkin untuk mencapai tugas ini:
def attempt1(string):
return "".join([v for v in string if v not in ("a", "e", "i", "o", "u")])
def attempt2(string):
for v in ("a", "e", "i", "o", "u"):
string = string.replace(v, "")
return string
def attempt3(string):
import re
for v in ("a", "e", "i", "o", "u"):
string = re.sub(v, "", string)
return string
def attempt4(string):
return string.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")
for attempt in [attempt1, attempt2, attempt3, attempt4]:
print(attempt("murcielago"))
PS: Bukannya menggunakan " ?.!/;:" contoh penggunaan vokal... dan ya, "murcielago" adalah kata spanyol untuk mengatakan bat... kata lucu karena mengandung semua vokal :)
PS2: Jika anda're tertarik pada kinerja anda bisa mengukur upaya ini dengan kode sederhana seperti:
import timeit
K = 1000000
for i in range(1,5):
t = timeit.Timer(
f"attempt{i}('murcielago')",
setup=f"from __main__ import attempt{i}"
).repeat(1, K)
print(f"attempt{i}",min(t))
Di dalam kotak saya, anda'd dapatkan:
attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465
Jadi sepertinya attempt4 adalah yang tercepat untuk input tertentu.
Berikut ini's my Python 2/3 versi yang kompatibel. Sejak translate api telah berubah.
def remove(str_, chars):
"""Removes each char in `chars` from `str_`.
Args:
str_: String to remove characters from
chars: String of to-be removed characters
Returns:
A copy of str_ with `chars` removed
Example:
remove("What?!?: darn;", " ?.!:;") => 'Whatdarn'
"""
try:
# Python2.x
return str_.translate(None, chars)
except TypeError:
# Python 3.x
table = {ord(char): None for char in chars}
return str_.translate(table)
Anda juga dapat menggunakan fungsi dalam rangka untuk mengganti jenis yang berbeda dari ekspresi reguler atau pola lainnya dengan menggunakan sebuah daftar. Dengan itu, anda dapat dicampur ekspresi reguler, kelas karakter, dan benar-benar dasar pola teks. It's benar-benar berguna ketika anda perlu untuk mengganti banyak elemen seperti HTML yang.
*NB: bekerja dengan Python 3.x
import re # Regular expression library
def string_cleanup(x, notwanted):
for item in notwanted:
x = re.sub(item, '', x)
return x
line = "<title>My example: <strong>A text %very% $clean!!</strong></title>"
print("Uncleaned: ", line)
# Get rid of html elements
html_elements = ["<title>", "</title>", "<strong>", "</strong>"]
line = string_cleanup(line, html_elements)
print("1st clean: ", line)
# Get rid of special characters
special_chars = ["[!@#$]", "%"]
line = string_cleanup(line, special_chars)
print("2nd clean: ", line)
Dalam fungsi string_cleanup, dibutuhkan string x dan daftar notwanted sebagai argumen. Untuk setiap item dalam daftar elemen-elemen atau pola, jika pengganti yang dibutuhkan itu akan dilakukan.
Output:
Uncleaned: <title>My example: <strong>A text %very% $clean!!</strong></title>
1st clean: My example: A text %very% $clean!!
2nd clean: My example: A text very clean
Saya metode I'd gunakan mungkin tidak't bekerja secara efisien, tetapi secara besar-besaran yang sederhana. Saya dapat menghapus beberapa karakter pada posisi yang berbeda sekaligus, menggunakan mengiris dan format. Berikut ini's contoh:
words = "things"
removed = "%s%s" % (words[:3], words[-1:])
Hal ini akan mengakibatkan 'dihapus' memegang kata-kata 'ini'.
Format dapat sangat membantu untuk pencetakan variabel midway melalui cetak string. Hal ini dapat memasukkan tipe data menggunakan a % diikuti oleh variabel's tipe data; semua tipe data dapat menggunakan %s, dan mengapung (alias desimal) dan bilangan bulat dapat menggunakan %d.
Mengiris dapat digunakan untuk kontrol yang rumit di atas senar. Ketika saya menempatkan kata-kata[:3], itu memungkinkan saya untuk memilih semua karakter dalam string dari awal (usus besar sebelum nomor, ini akan berarti 'dari awal sampai') untuk ke-4 karakter (termasuk 4 karakter). Alasannya sama dengan 3 sampai 4 posisi ini karena Python dimulai dari 0. Kemudian, ketika saya menempatkan kata[-1:], itu berarti 2 karakter terakhir sampai akhir (usus besar di balik nomor). Menempatkan -1 akan membuat Python menghitung dari karakter terakhir, bukan yang pertama. Lagi, Python akan dimulai dari 0. Jadi, kata[-1:] pada dasarnya berarti 'dari kedua karakter terakhir ke akhir dari string.
Jadi, dengan memotong karakter sebelum karakter saya ingin menghapus dan karakter setelah dan mengapit mereka bersama-sama, saya dapat menghapus karakter yang tidak diinginkan. Anggap saja seperti sosis. Di tengah itu's kotor, jadi saya ingin menyingkirkan itu. Saya hanya memotong kedua ujung saya inginkan kemudian menempatkan mereka bersama-sama tanpa bagian yang tidak diinginkan di tengah.
Jika saya ingin menghapus beberapa berturut-turut karakter, saya hanya menggeser angka-angka di dalam [] (mengiris bagian). Atau jika saya ingin menghapus beberapa karakter dari posisi yang berbeda, saya hanya dapat sandwich bersama beberapa potong sekaligus.
Contoh:
words = "control"
removed = "%s%s" % (words[:2], words[-2:])
dihapus sama 'keren'.
words = "impacts"
removed = "%s%s%s" % (words[1], words[3:5], words[-1])
dihapus sama 'mac'.
Dalam hal ini, [3:5] berarti karakter di posisi 3 melalui karakter di posisi 5 (tidak termasuk karakter pada posisi akhir).
Ingat, Python mulai menghitung dari 0, sehingga anda akan perlu untuk juga.
#!/usr/bin/python
import re
strs = "how^ much for{} the maple syrup? $20.99? That's[] ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!|a|b]',r' ',strs)#i have taken special character to remove but any #character can be added here
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)#for removing special character
print nestr
String metode menggantikan
tidak memodifikasi string asli. Daun asli sendirian dan kembali salinan dimodifikasi.
Apa yang anda inginkan adalah sesuatu seperti: line = garis.replace(char,'')
def replace_all(line, )for char in line:
if char in " ?.!/;:":
line = line.replace(char,'')
return line
Namun, menciptakan sebuah string baru masing-masing dan setiap kali karakter yang dihapus adalah sangat tidak efisien. Saya sarankan berikut ini sebagai gantinya:
def replace_all(line, baddies, *):
"""
The following is documentation on how to use the class,
without reference to the implementation details:
For implementation notes, please see comments begining with `#`
in the source file.
[*crickets chirp*]
"""
is_bad = lambda ch, baddies=baddies: return ch in baddies
filter_baddies = lambda ch, *, is_bad=is_bad: "" if is_bad(ch) else ch
mahp = replace_all.map(filter_baddies, line)
return replace_all.join('', join(mahp))
# -------------------------------------------------
# WHY `baddies=baddies`?!?
# `is_bad=is_bad`
# -------------------------------------------------
# Default arguments to a lambda function are evaluated
# at the same time as when a lambda function is
# **defined**.
#
# global variables of a lambda function
# are evaluated when the lambda function is
# **called**
#
# The following prints "as yellow as snow"
#
# fleece_color = "white"
# little_lamb = lambda end: return "as " + fleece_color + end
#
# # sometime later...
#
# fleece_color = "yellow"
# print(little_lamb(" as snow"))
# --------------------------------------------------
replace_all.map = map
replace_all.join = str.join