问题描述
我正在尝试使用 Python 3.7 从包含重音符号的字符串中删除所有非字母字符(空格除外).我尝试了以下方法:
I'm trying to delete all non-letter chars (except white-space) from a string containing accents using Python 3.7. I tried the following:
import re
text = "Андре́й Серге́евич Арша́вин (род. 29 мая 1981[4], Ленинград) — российский футболист, бывший капитан сборной России, заслуженный мастер спорта России (2008)."
clean_text = re.sub('[\W_\d]+', ' ', text)
print(clean_text)
输出是
Андре й Серге евич Арша вин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
为什么我的结果字符串中的重音字符后面有一个空格?这似乎违反了最小惊喜原则.所以我尝试了不同的解决方案
Why do I get a whitespace after the accented char in my result string? This seems to violate the principle of least surprise. So I tried a different solution
文本= АндрейСергеевичАршавин(род29мая1981 [4],Ленинград) - российскийфутболист,бывшийкапитансборнойРоссии,заслуженныймастерспортаРоссии(2008)"clean_text2 = "".join(c for c in text if c.isalpha() or c == " ")打印(clean_text2)
输出是
Андрей Сергеевич Аршавин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
这几乎是我想要的,只是它从字符中删除了重音.我想得到以下结果:
This is nearly what I wanted, except that it removes the accents from the chars. I would like to have the following result:
Андре́й Серге́евич Арша́вин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
有没有办法从字符串中删除所有非字母字符,但保留字符上的重音符号?
Is there a way to remove all non-letter chars from a string, but keep the accents on the chars?
推荐答案
俄语单词重音符号基本解决方案
俄语字母没有重音,你在字符串中的重音显示单词重音,并且只用于特定的书面语音,如外国人教科书、儿童书籍等.
Russian letters do not have accents, the accent you have in the string shows the word stress, and is only used in specific written speech, like in textbooks for foreigners, books for children, etc.
е́
是一个 e
字母和 \u0301
字符,0301 COMBINING ACUTE ACCENT
.可以从您的模式中减去唯一的重音符号以获得您想要的结果:
The е́
is a e
letter and the \u0301
char, 0301 COMBINING ACUTE ACCENT
. The only accent diacritic can be subtracted from your pattern to get the results you want:
clean_text = re.sub(r'(?:(?!\u0301)[\W\d_])+', ' ', text)
查看 Python 演示 产出
Андре́й Серге́евич Арша́вин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
查看正则表达式在线演示.
支持所有变音符号的解决方案 - PyPi 正则表达式模块
要保留所有变音符号,最简单的方法是安装 PyPi 正则表达式模块(使用 pip install regex
) 然后使用 \p{L}
和 \p{M}
Unicode 属性类:
To keep all diacritic marks, the easiest is to install PyPi regex module (with pip install regex
) and then use \p{L}
and \p{M}
Unicode property classes:
import regex
text = "Андре́й Серге́евич Арша́вин (род. 29 мая 1981[4], Ленинград) — российский футболист, бывший капитан сборной России, заслуженный мастер спорта России (2008)."
print ( regex.sub(r'[^\p{L}\p{M}]+', ' ', text) )
# => Андре́й Серге́евич Арша́вин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
print( " ".join(regex.findall(r'(?>\p{L}\p{M}*+)+', text)) )
# => Андре́й Серге́евич Арша́вин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
这里,\[^\p{L}\p{M}\]+
regex 匹配除 Unicode 字母 (\p{L}
) 和变音符号 (\p{M}
) 之外的任何 1 个或多个字符.另一个解决方案,(?>\p{L}\p{M}*+)+
和 re.findall
,从文本中提取所有字母 + 变音符号块,然后 " ".join(...)
连接它们有空格.
Here, \[^\p{L}\p{M}\]+
regex matches any 1 or more chars other than Unicode letters (\p{L}
) and diacritic characters (\p{M}
). The other solution, (?>\p{L}\p{M}*+)+
with re.findall
, extracts all letter + diacritic chunks from the text and then " ".join(...)
concats them with a space.
Python 的变音符号支持 re
您需要拼写"\p{M}
类,并且您可以使用 [^\W\d_]
构造匹配任何 Unicode 字母.在这里使用 find-all-words-and-then-concatenate 方法而不是 re.sub
是有意义的:
You will need to "spell out" the \p{M}
class and you may match any Unicode letter using [^\W\d_]
construct. It makes sense to use the find-all-words-and-then-concatenate approach here rather than re.sub
:
import re
combining_marks_bmp = '\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F'
combining_marks_astral = '\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDDDC\uDDDD\uDE30-\uDE40\uDEAB-\uDEB7\uDF1D-\uDF2B]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDDCA-\uDDCC\uDE2C-\uDE37\uDEDF-\uDEEA\uDF00-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD82F[\uDC9D\uDC9E]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]'
letter = r'[^\W\d_]'
pat = re.compile(r'(?:{}|[{}]|{})+'.format(letter,combining_marks_bmp, combining_marks_astral))
print(" ".join(pat.findall(text)))
# => Андре́й Серге́евич Арша́вин род мая Ленинград российский футболист бывший капитан сборной России заслуженный мастер спорта России
这篇关于从 Python 中带重音的字符串中删除所有非字母字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!