2016-04-16 2 views
5

У меня есть строка, которая содержит как арабские, так и английские предложения. Я хочу только извлечь арабские предложения.Как получить только арабские тексты из строки, используя регулярное выражение?

my_string=""" 
What is the reason 
ذَلِكَ الْكِتَابُ لَا رَيْبَ فِيهِ هُدًى لِلْمُتَّقِينَ 
behind this? 
ذَلِكَ الْكِتَابُ لَا رَيْبَ فِيهِ هُدًى لِلْمُتَّقِينَ 
""" 

This Link показывает, что диапазон Юникода для арабских букв 0600-06FF.

Итак, очень простой попытка пришла мне в голову:

import re 
print re.findall(r'[\u0600-\u06FF]+',my_string) 

Но это не жалко, как он возвращает следующий список.

['What', 'is', 'the', 'reason', 'behind', 'this?'] 

Как вы можете видеть, это точно противоположно тому, что я хочу. Что мне здесь не хватает?

N.B.

Я знаю, что могу соответствовать арабские буквы с помощью обратного соответствия, как показано ниже:

print re.findall(r'[^a-zA-Z\s0-9]+',my_string) 

Но я не хочу этого.

ответ

4

Вы можете использовать re.sub, чтобы заменить символы ascii пустой строкой.

>>> my_string=""" 
... What is the reason 
... ذَلِكَ الْكِتَابُ لَا رَيْبَ فِيهِ هُدًى لِلْمُتَّقِينَ 
... behind this? 
... ذَلِكَ الْكِتَابُ لَا رَيْبَ فِيهِ هُدًى لِلْمُتَّقِينَ 
... """ 
>>> print(re.sub(r'[a-zA-Z?]', '', my_string).strip()) 
ذَلِكَ الْكِتَابُ لَا رَيْبَ فِيهِ هُدًى لِلْمُتَّقِينَ 

ذَلِكَ الْكِتَابُ لَا رَيْبَ فِيهِ هُدًى لِلْمُتَّقِينَ 

Ваше регулярное выражение не работает, потому что вы используете Python 2 и ваша строка str вам нужно конвертировать my_string в юникод для его работы. Однако это прекрасно работает на Python3.x

>>> print "".join(re.findall(ur'[\u0600-\u06FF]', unicode(my_string, "utf-8"), re.UNICODE)) 
ذَلِكَالْكِتَابُلَارَيْبَفِيهِهُدًىلِلْمُتَّقِينَذَلِكَالْكِتَابُلَارَيْبَفِيهِهُدًىلِلْمُتَّقِينَ 
+0

Спасибо за хороший ответ, +1 Но почему эта попытка не работает? –

+0

Я удовлетворен :) Спасибо –

2

Ваш исходный код был правильным, просто необходимо, чтобы закодировать my_string с продходящим, «UTF-8» и добавить u в вашем re шаблоне, так как вы работаете с python2,

>>> for x in re.findall(ur'[\u0600-\u06FF]+', my_string.decode('utf-8')): 
     print x 


ذَلِكَ 
الْكِتَابُ 
لَا 
رَيْبَ 
فِيهِ 
هُدًى 
لِلْمُتَّقِينَ 
ذَلِكَ 
الْكِتَابُ 
لَا 
رَيْبَ 
فِيهِ 
هُدًى 
لِلْمُتَّقِينَ 

Это даст вам список соответствующих строк Юникода вместо одиночных символов, которые вам не нужны, чтобы присоединиться к ним обратно с ''.join

Если вы были в Python3, вы не п ПЕД любой кодировки tweeking как кодирование по умолчанию является «UTF-8»:

>>> for x in re.findall(r'[\u0600-\u06FF]+', my_string): 
     print(x) 


ذَلِكَ 
الْكِتَابُ 
لَا 
رَيْبَ 
فِيهِ 
هُدًى 
لِلْمُتَّقِينَ 
ذَلِكَ 
الْكِتَابُ 
لَا 
رَيْبَ 
فِيهِ 
هُدًى 
لِلْمُتَّقِينَ 
2

Ваш код:

print re.findall(r'[\u0600-\u06FF]+',my_string) 

При сопоставлении последовательность байт, не существует такого понятия, как точки кода Unicode. Следовательно, escape-последовательности \u в регулярном выражении не имеют никакого смысла. Они не интерпретируются, как вы думали, а просто означают u.

Так при разборе регулярного выражения для байт, это эквивалентно:

print re.findall(r'[u0600-u06FF]+',my_string) 

Этого класс символов интерпретируются как «один из u060 или байт в диапазоне 0-u, или один из 06FF». Это, в свою очередь, эквивалентно [0-u], так как все остальные байты уже включены в этот диапазон.

print re.findall(r'[0-u]+', my_string) 

Демонстрация:

my_string = "What is thizz?" 
print re.findall(r'[\u0600-\u06FF]+',my_string) 
['What', 'is', 'thi', '?'] 

Обратите внимание, что zz не соответствует, так как он приходит за u в наборе ASCII символов.

+0

Это лучшее объяснение ситуации. Хотел бы я сделать +2. Спасибо mate :) –

+1

не следует читать: «один из ** u060 ** или байт в диапазоне * 0-u *, или один из * 06FF *» – sweaver2112

+0

Большое спасибо за ваше тщательное чтение. Я исправил это. –

Смежные вопросы