赛派号

生普和熟普哪个能放的时间长 بايثون

بايثون - كيف يمكن استبدال عدة سلاسل جزئية في النص؟

أود استخدام دالة .replace لاستبدال عدة سلاسل نصية.

لدي حالياً

string.replace("condition1", "")

لكن أود أن يكون لدي شيء مثل

string.replace("condition1", "").replace("condition2", "text")

على الرغم من أن ذلك لا يبدو مثل بناء جملة جيد

ما هي الطريقة الصحيحة للقيام بذلك؟ مشابهة للطريقة التي يمكنك بها في grep/regex استخدام \1 و \2 لاستبدال الحقول بسلاسل البحث معينة

الإجابة رقم 1

إليك مثال قصير يجب أن ينجز المهمة مع التعبيرات النمطية:

import re rep = {"condition1": "", "condition2": "text"} # define desired replacements here use these three lines to do the replacement rep = dict((re.escape(k), v) for k, v in rep.items()) pattern = re.compile("|".join(rep.keys())) text = pattern.sub(lambda m: rep[re.escape(m.group(0))], text)

على سبيل المثال:

>>> pattern.sub(lambda m: rep[re.escape(m.group(0))], "(condition1) and --condition2--") '() and --text--' الإجابة رقم 2

يمكنك فقط إنشاء دالة صغيرة جميلة تعمل بشكل متكرر.

def replace_all(text, dic): for i, j in dic.iteritems(): text = text.replace(i, j) return text

حيث أن text هو السلسلة الكاملة و dic هو قاموس — كل تعريف هو سلسلة ستستبدل المطابقة للمصطلح.

ملاحظة: في بايثون 3، تم استبدال iteritems() بـ items()

تنبيه: القواميس في بايثون لا تمتلك ترتيبًا موثوقًا به للتكرار. هذا الحل يحل مشكلتك فقط إذا:

ترتيب الاستبدالات غير مهملا بأس في أن يؤدي الاستبدال إلى تغيير نتائج الاستبدالات السابقة

تحديث: البيان أعلاه المتعلق بترتيب الإدراج لا ينطبق على إصدارات بايثون الأكبر من أو تساوي 3.6، حيث تم تغيير القواميس القياسية لاستخدام ترتيب الإدراج أثناء التكرار.

على سبيل المثال:

d = { "cat": "dog", "dog": "pig"} my_sentence = "This is my cat and this is my dog." replace_all(my_sentence, d) print(my_sentence)

الإخراج المحتمل #1:

"This is my pig and this is my pig."

المخرج المحتمل #2

"This is my dog and this is my pig."

إحدى الحلول الممكنة هي استخدام OrderedDict.

from collections import OrderedDict def replace_all(text, dic): for i, j in dic.items(): text = text.replace(i, j) return text od = OrderedDict([("cat", "dog"), ("dog", "pig")]) my_sentence = "This is my cat and this is my dog." replace_all(my_sentence, od) print(my_sentence)

الناتج :

"This is my pig and this is my pig."

تحذير #2: غير فعال إذا كانت سلسلة text كبيرة جدًا أو إذا كانت هناك العديد من الأزواج في القاموس.

الإجابة رقم 3

لماذا لا يكون هناك حل واحد مثل هذا؟

s = "The quick brown fox jumps over the lazy dog" for r in (("brown", "red"), ("lazy", "quick")): s = s.replace(*r) #output will be: The quick red fox jumps over the quick dog الإجابة رقم 4

إليك نسخة من الحل الأول باستخدام reduce (استيراد من functools)، في حال كنت تحب الأسلوب الوظيفي. :)

repls = {'hello' : 'goodbye', 'world' : 'earth'} s = 'hello, world' reduce(lambda a, kv: a.replace(*kv), repls.iteritems(), s)

نسخة مارتينو الأفضل:

repls = ('hello', 'goodbye'), ('world', 'earth') s = 'hello, world' reduce(lambda a, kv: a.replace(*kv), repls, s) الإجابة رقم 5

هذا مجرد ملخص أكثر إيجازًا لإجابات F.J و MiniQuark الرائعة وأخيرًا التحسين الحاسم من bgusach. كل ما تحتاجه لتحقيق استبدالات متعددة للسلاسل في نفس الوقت هو الدالة التالية:

import re def multiple_replace(string, rep_dict): pattern = re.compile("|".join([re.escape(k) for k in sorted(rep_dict,key=len,reverse=True)]), flags=re.DOTALL) return pattern.sub(lambda x: rep_dict[x.group(0)], string)

الاستخدام :

>>>multiple_replace("Do you like cafe? No, I prefer tea.", {'cafe':'tea', 'tea':'cafe', 'like':'prefer'}) 'Do you prefer tea? No, I prefer cafe.'

إذا رغبت، يمكنك إنشاء دوال استبدال مخصصة خاصة بك بدءًا من هذه الدالة الأبسط.

الإجابة رقم 6

بدءًا من Python 3.8، ومع تقديم تعابير الإسناد (PEP 572) (المشغّل :=)، يمكننا تطبيق الاستبدالات ضمن استيعاب القائمة:

text = "The quick brown fox jumps over the lazy dog" replacements = [("brown", "red"), ("lazy", "quick")] [text := text.replace(a, b) for a, b in replacements] text = 'The quick red fox jumps over the quick dog' الإجابة رقم 7

بنيت هذا اعتمادًا على إجابة F.J الممتازة:

import re def multiple_replacer(*key_values): replace_dict = dict(key_values) replacement_function = lambda match: replace_dict[match.group(0)] pattern = re.compile("|".join([re.escape(k) for k, v in key_values]), re.M) return lambda string: pattern.sub(replacement_function, string) def multiple_replace(string, *key_values): return multiple_replacer(*key_values)(string)

استخدام لمرة واحدة:

>>> replacements = (u"café", u"tea"), (u"tea", u"café"), (u"like", u"love") >>> print multiple_replace(u"Do you like café? No, I prefer tea.", *replacements) Do you love tea? No, I prefer café.

لاحظ أنه نظرًا لأن الاستبدال يتم في تمريرة واحدة فقط، فإن "café" تتغير إلى "tea"، لكنها لا تعود إلى "café".

إذا كنت بحاجة للقيام بنفس الاستبدال عدة مرات، يمكنك إنشاء دالة استبدال بسهولة:

>>> my_escaper = multiple_replacer(('"','\\"'), ('\t', '\\t')) >>> many_many_strings = (u'This text will be escaped by "my_escaper"', u'Does this work?\tYes it does', u'And can we span\nmultiple lines?\t"Yes\twe\tcan!"') >>> for line in many_many_strings: ... print my_escaper(line) ... This text will be escaped by \"my_escaper\" Does this work?\tYes it does And can we span multiple lines?\t\"Yes\twe\tcan!\"

تحسينات:

حوَّل الكود إلى دالةتمت إضافة دعم متعدد الأسطرتم إصلاح خطأ في الهروبمن السهل إنشاء دالة لاستبدال عدة عناصر محددة

استمتع! :-)

الإجابة رقم 8

أود أن أقترح استخدام قوالب السلاسل. فقط ضع السلسلة المراد استبدالها في قاموس وكل شيء جاهز! مثال من docs.python.org

>>> from string import Template >>> s = Template('$who likes $what') >>> s.substitute(who='tim', what='kung pao') 'tim likes kung pao' >>> d = dict(who='tim') >>> Template('Give $who $100').substitute(d) Traceback (most recent call last): [...] ValueError: Invalid placeholder in string: line 1, col 10 >>> Template('$who likes $what').substitute(d) Traceback (most recent call last): [...] KeyError: 'what' >>> Template('$who likes $what').safe_substitute(d) 'tim likes $what' الإجابة رقم 9

هذه وجهة نظري بقيمة 0.02 دولار. وهي مستندة على إجابة أندرو كلارك، لكنها أوضح قليلاً، وتشمل أيضاً الحالة التي يكون فيها النص المراد استبداله جزءًا من نص آخر يجب استبداله (النص الأطول هو الذي يُستبدل).

def multireplace(string, replacements): """ Given a string and a replacement map, it returns the replaced string. :param str string: string to execute replacements on :param dict replacements: replacement dictionary {value to find: value to replace} :rtype: str """ # Place longer ones first to keep shorter substrings from matching # where the longer ones should take place # For instance given the replacements {'ab': 'AB', 'abc': 'ABC'} against # the string 'hey abc', it should produce 'hey ABC' and not 'hey ABc' substrs = sorted(replacements, key=len, reverse=True) # Create a big OR regex that matches any of the substrings to replace regexp = re.compile('|'.join(map(re.escape, substrs))) # For each match, look up the new string in the replacements return regexp.sub(lambda match: replacements[match.group(0)], string)

إنه موجود في هذا الملخص، لا تتردد في تعديله إذا كان لديك أي اقتراح.

الإجابة رقم 10

في حالتي، كنت بحاجة إلى استبدال بسيط للمفاتيح الفريدة بالأسماء، لذا خطرت لي هذه الفكرة:

a = 'This is a test string.' b = {'i': 'I', 's': 'S'} for x,y in b.items(): a = a.replace(x, y) >>> a 'ThIS IS a teSt StrIng.'

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lsinopec@gmail.com举报,一经查实,本站将立刻删除。

上一篇 没有了

下一篇没有了