Python 2 re.sub issue

余生长醉 提交于 2019-12-11 09:58:36

问题


I got this a function that replaces sub-string matches with the match surrounded with HTML tags. This function will consume string in English and Greek mostly.

The function:

def highlight_text(st, kwlist, start_tag=None, end_tag=None):
    if start_tag is None:
        start_tag = '<span class="nom">'

    if end_tag is None:
        end_tag = '</span>'

    for kw in kwlist:
        st = re.sub(r'\b' + kw + r'\b', '{}{}{}'.format(start_tag, kw, end_tag), st)
    return st

The testing string is in Greek except the first sub-string [Korais]: st="Korais Ο Αδαμάντιος Κοραής (Σμύρνη, 27 Απριλίου 1748 – Παρίσι, 6 Απριλίου 1833), ήταν Έλληνας φιλόλογος με βαθιά γνώση του ελληνικού πολιτισμού. Ο Κοραής είναι ένας από τους σημαντικότερους εκπροσώπους του νεοελληνικού διαφωτισμού και μνημονεύεται, ανάμεσα σε άλλα, ως πρωτοπόρος στην έκδοση έργων αρχαίας ελληνικής γραμματείας, αλλά και για τις γλωσσικές του απόψεις στην υποστήριξη της καθαρεύουσας, σε μια μετριοπαθή όμως μορφή της με σκοπό την εκκαθάριση των πλείστων ξένων λέξεων που υπήρχαν στη γλώσσα του λαού."

The test code:

kwlist = ['ελληνικού', 'Σμύρνη', 'Αδαμάντιος', 'Korais']
d = highlight_text(st, kwlist, start_tag=None, end_tag=None)
print(d)

When I'm running the code [st is the above string] only sub-strings in English get tagged. Greek substr are ignored. Notice that I run the above block on Python 2.7. When I use Python 3.4 all sub-string get replaced. Another issue is that when I'm running the above function withing Flask application, it throws me an error: unexpected end of regular expression.

How should I tackle the above issue without using external library if possible? I'm pulling my hairs off my head two days now.


回答1:


In Python 2.7, you need to explicitly convert text to Unicode. See the fixed snippet below:

# -*- coding: utf-8 -*-
import re
def highlight_text(st, kwlist, start_tag=None, end_tag=None):
    if start_tag is None:
        start_tag = '<span class="nom">'

    if end_tag is None:
        end_tag = '</span>'

    for kw in kwlist:
        st = re.sub(ur'\b' + kw.decode('utf8') + ur'\b', 
           u'{}{}{}'.format(start_tag.decode('utf8'), kw.decode('utf8'), end_tag.decode('utf8')),
           st.decode('utf8'), 0, re.U).encode("utf8")
    return st

st="Korais Ο Αδαμάντιος Κοραής (Σμύρνη, 27 Απριλίου 1748 – Παρίσι, 6 Απριλίου 1833), ήταν Έλληνας φιλόλογος με βαθιά γνώση του ελληνικού πολιτισμού. Ο Κοραής είναι ένας από τους σημαντικότερους εκπροσώπους του νεοελληνικού διαφωτισμού και μνημονεύεται, ανάμεσα σε άλλα, ως πρωτοπόρος στην έκδοση έργων αρχαίας ελληνικής γραμματείας, αλλά και για τις γλωσσικές του απόψεις στην υποστήριξη της καθαρεύουσας, σε μια μετριοπαθή όμως μορφή της με σκοπό την εκκαθάριση των πλείστων ξένων λέξεων που υπήρχαν στη γλώσσα του λαού."
kwlist = ['ελληνικού', 'Σμύρνη', 'Αδαμάντιος', 'Korais']
d = highlight_text(st, kwlist, start_tag=None, end_tag=None)
print(d)

See demo

Note that all literals are declared with u prefix and all variables are decodeed and the re.sub result is encoded back to UTF8.




回答2:


English get tagged. Greek substr are ignored.

Where does your st come from? Please notice that in Python 2.x 'μορφή' != u'μορφή' Maybe you are comparing str with unicode.

Suggestions: Use unicode everywhere when you can, e.g.:

kwlist = [u'ελληνικού', u'Σμύρνη', u'Αδαμάντιος', u'Korais']


来源:https://stackoverflow.com/questions/34672071/python-2-re-sub-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!