我有一个波斯语文本文件,其中有一些这样的行:
ذوب 6 خوی 7 بزاق ،آبدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف
我想从这一行生成一个单词列表。对我来说,单词border是上面一行中的数字,如6,7等,还有،
字符。
所以列表应该是:
[ 'ذوب','خوی','بزاق','آبدهان','یم','زهاب','آبرو','حیثیت' ,'شرف']
我想在Python 3.3中这样做。 这样做的最佳方式是什么,我真的很感激任何帮助。
修改
我得到了许多答案,但当我将它们用于另一个测试用例时,它们无法正常工作。测试案例如下:
منهدم کردن : 1 خراب کردن، ویران کردن، تخریب کردن 2 نابود کردن، از بین بردن
我希望有一个令牌列表:
['منهدم کردن','خراب کردن', 'ویران کردن', 'تخریب کردن','نابود کردن', 'از بین بردن']
答案 0 :(得分:3)
>>> import regex
>>> text = 'ذوب 6 خوی 7 بزاق ،آبدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف'
>>> regex.findall(r'\p{L}+', text.replace('\u200c', ''))
['ذوب', 'خوی', 'بزاق', 'آبدهان', 'یم', 'زهاب', 'آبرو', 'حیثیت', 'شرف']
str.replace
删除了该字符。\p{L}
或\p{Letter}
匹配来自任何语言的任何类型的字母。请参阅Regex Tutorial - Unicode Characters and Properties。
<强>更新强>
要同时包含U + 200C,请使用[\p{Cf}\p{L}]+
代替(\p{Cf}
或\p{Format}
匹配不可见的格式化字符):
>>> regex.findall(r'[\p{Cf}\p{L}]+', text)
['ذوب', 'خوی', 'بزاق', 'آب\u200cدهان', 'یم', 'زهاب', 'آبرو', 'حیثیت', 'شرف']
它看起来与你想要的不同,但它们是平等的:
>>> got = regex.findall(r'[\p{Cf}\p{L}]+', text)
>>> want = [ 'ذوب','خوی','بزاق','آبدهان','یم','زهاب','آبرو','حیثیت' ,'شرف']
>>> print(want)
['ذوب', 'خوی', 'بزاق', 'آب\u200cدهان', 'یم', 'زهاب', 'آبرو', 'حیثیت', 'شرف']
>>> got == want
>>> got[:3]
['ذوب', 'خوی', 'بزاق']
>>> got[4:]
['یم', 'زهاب', 'آبرو', 'حیثیت', 'شرف']
<强> UPDATE2 强>
编辑过的问题中的某些单词包含空格。
>>> ' ' in 'منهدم کردن'
True
我在以下代码中添加\s
以匹配空格,然后从匹配的字符串中删除前导空格,然后过滤掉空字符串。
>>> text = 'منهدم کردن : 1 خراب کردن، ویران کردن، تخریب کردن 2 نابود کردن، از بین بردن'
>>> want = ['منهدم کردن','خراب کردن', 'ویران کردن', 'تخریب کردن','نابود کردن', 'از بین بردن']
>>> [x for x in map(str.strip, regex.findall(r'[\p{Cf}\p{L}\s]+', text)) if x] == want
True
答案 1 :(得分:1)
使用re.split
分隔空格(\s
),数字(\d
)和،
字符。
# python 3
import re
INPUT = 'ذوب 6 خوی 7 بزاق ،آبدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف'
EXPECTED = [ 'ذوب','خوی','بزاق','آبدهان','یم','زهاب','آبرو','حیثیت' ,'شرف']
OUTPUT = re.split('[\s\d،]+', INPUT)
assert OUTPUT == EXPECTED
print('\n'.join(OUTPUT))
请注意,您在输出数组中看到的\u200c
是非打印字符,实际上包含在原始字符串中。 Python正在逃避它,因为它显示数组的表示并包含字符串,而不是打印字符串以供显示。这是区别:
INPUT = 'ذوب 6 خوی 7 بزاق ،آبدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف'
print(INPUT)
ذوب 6 خوی 7 بزاق ،آبدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف
print(repr(INPUT)) # notice the \u200c below
'ذوب 6 خوی 7 بزاق ،آب\u200cدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف'
print(['in', 'an', 'array', INPUT]) # the \u200c is also shown when printing an array
['in', 'an', 'array', 'ذوب 6 خوی 7 بزاق ،آب\u200cدهان ، یم 10 زهاب، 11 آبرو، حیثیت، شرف']
这类似于python处理newline
字符的方式:
>>> 'new\nline'
'new\nline'
>>> print 'new\nline'
new
line
修改强>
以下是使用了falsetru的findall策略的更新示例的正则表达式,但使用了内置的re
模块:
OUTPUT = [s.strip() for s in re.findall(r'(?:[^\W\d_]|[\s])+', INPUT) if s.strip()]
模式(?:[^\W\d_]|[\s])+
有点奇怪,因为Python的re模块与正则表达式的“Letters”\p{L}
不相同,所以我们使用此处提出的解决方案https://stackoverflow.com/a/8923988/66349
[^\W\d_] - (not ((not alphanumeric) or digits or underscore))
总而言之,匹配一个或多个(+
)字符(|
):Unicode字母[^\W\d_
或空格\s
。
falsetru的方法可能更具可读性,但需要第三方库。