Python: استبدل String بـ prefixstringsuffix الحفاظ على الحالة الأصلية ، ولكن تجاهل الحالة عند البحث عن المطابقة

StackOverflow https://stackoverflow.com/questions/818691

سؤال

إذن ما أحاول القيام به هو استبدال سلسلة "الكلمة الرئيسية" "<b>keyword</b>"في سلسلة أكبر.

مثال:

myString = "مرحبًا ، يجب عليك أعلى هذا الشخص للوظيفة. مرحبًا مرحبًا."

الكلمة الرئيسية = "مرحبا"

النتيجة التي أريدها ستكون:

result = "<b>HI</b> there. You should higher that person for the job. <b>Hi</b> <b>hi</b>."

لن أعرف ما هي الكلمة الرئيسية حتى يقوم المستخدم بتكوين الكلمة الرئيسية ولن يعرف المجموعة (mystring) حتى يتم تشغيل الاستعلام.

لقد وجدت حلاً يعمل معظم الوقت ، لكن لديه بعض الإيجابيات الخاطئة ،namely it would return "<b>hi<b/>gher"وهو ليس ما أريد. لاحظ أيضًا أنني أحاول الحفاظ على حالة النص الأصلي ، ويجب أن تتم المطابقة بغض النظر عن الحالة. لذلك إذا كانت الكلمة الرئيسية "مرحبًا" ، فيجب استبدالهاHI with <b>HI</b> and hi with <b>hi</b>.

أقرب ما أتيت هو استخدام نسخة مشتقة قليلاً من هذا:http://code.activestate.com/recipes/576715/لكن ما زلت لا أستطيع معرفة كيفية إجراء تمريرة ثانية من السلسلة لإصلاح جميع الإيجابيات الخاطئة المذكورة أعلاه.

أو باستخدام WordPunctTokenizer من NLTK (الذي يبسط بعض الأشياء مثل علامات الترقيم) ، لكنني لست متأكدًا من كيفية إعادة الجمل معًا بالنظر إلى أنه لا يحتوي على وظيفة عكسية وأريد الحفاظ على علامات الترقيم الأصلية لمخلفات البرلمان. من الضروري أن يؤدي التسلسل لجميع الرموز إلى إرجاع السلسلة الأصلية. على سبيل المثال ، لا أرغب في استبدال "7 - 7" بـ "7-7" عند إعادة تجميع الرموز في نصها الأصلي إذا كان النص الأصلي "7 - 7".

أتمنى أن يكون ذلك واضحًا بما فيه الكفاية. يبدو وكأنه مشكلة بسيطة ، لكنها تحولت إلى أكثر صعوبة بعض الشيء ثم اعتقدت.

هل كانت مفيدة؟

المحلول

هذا موافق؟

>>> import re
>>> myString = "HI there. You should higher that person for the job. Hi hi."
>>> keyword = "hi"
>>> search = re.compile(r'\b(%s)\b' % keyword, re.I)
>>> search.sub('<b>\\1</b>', myString)
'<b>HI</b> there. You should higher that person for the job. <b>Hi</b> <b>hi</b>.'

مفتاح كل شيء هو استخدام حدود الكلمات, مجموعات و ال إعادة العلم.

نصائح أخرى

يجب أن تكون قادرًا على القيام بذلك بسهولة شديدة re.sub باستخدام كلمة تأكيد الحدود \b, ، الذي يتطابق فقط مع حدود الكلمة:

import re

def SurroundWith(text, keyword, before, after):
  regex = re.compile(r'\b%s\b' % keyword, re.IGNORECASE)
  return regex.sub(r'%s\0%s' % (before, after), text)

ثم تحصل على:

>>> SurroundWith('HI there. You should hire that person for the job. '
...              'Hi hi.', 'hi', '<b>', '</b>')
'<b>HI</b> there. You should hire that person for the job. <b>Hi</b> <b>hi</b>.'

إذا كان لديك معايير أكثر تعقيدًا لما يشكل "حدود الكلمة" ، فسيتعين عليك القيام بشيء مثل:

def SurroundWith2(text, keyword, before, after):
  regex = re.compile(r'([^a-zA-Z0-9])(%s)([^a-zA-Z0-9])' % keyword,
                     re.IGNORECASE)
  return regex.sub(r'\1%s\2%s\3' % (before, after), text)

يمكنك تعديل [^a-zA-Z0-9] مجموعات لتتناسب مع أي شيء تعتبره "غير الكلمة".

أعتقد أن أفضل حل سيكون تعبيرًا منتظمًا ...

import re
def reg(keyword, myString) :
   regx = re.compile(r'\b(' + keyword + r')\b', re.IGNORECASE)
   return regx.sub(r'<b>\1</b>', myString)

بالطبع ، يجب عليك أولاً جعل الكلمة الرئيسية "تعبيرًا عاديًا آمنًا" (اقتبس من أي شخصيات خاصة regex).

إليك اقتراح واحد ، من لجنة Nitpicking. :-)

myString = "HI there. You should higher that person for the job. Hi hi."

myString.replace('higher','hire')
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top