Разделение между ивритом и английскими строками

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

Я попробовал глупый метод сравнения каждого символа:

import string
data = []
for s in slist:
    found = False
    for c in string.ascii_letters:
        if c in s:
            found = True
    if not found:
        data.append(s)

И это работает, но это, конечно, очень медленно, и мой список огромен. Вместо этого я попытался сравнить только первую букву строки с string.ascii_letters который был намного быстрее, но он отфильтровывает только те, которые начинаются с английской буквы, и оставляет там "смешанные" строки. Я хочу только те, которые "чистый" иврит.

Я уверен, что это можно сделать намного лучше... Помогите, кто-нибудь?

PS: я предпочитаю делать это в программе на python, но команда grep, которая делает то же самое, также поможет

5 ответов

Решение

Чтобы проверить, содержит ли строка какие-либо буквы ASCII (т. Е. Не на иврите), используйте:

re.search('[' + string.ascii_letters + ']', s)

Если это возвращает true, ваша строка не является чистым ивритом.

Этот должен работать:

import re
data = [s for s in slist if re.match('^[a-zA-Z ]+$', s)]

Это выберет все строки, которые состоят из строчных и прописных английских букв и пробелов. Если строки могут содержать цифры или знаки пунктуации, разрешенные символы должны быть включены в регулярное выражение.

Изменить: Только что заметил, он отфильтровывает строки только на английском языке, но вам нужно, чтобы все было наоборот. Вы можете попробовать это вместо этого:

data = [s for s in slist if not re.match('^.*[a-zA-Z].*$', s)]

Это исключит любую строку, которая содержит хотя бы одну английскую букву.

Python имеет обширную поддержку юникода. Это зависит от того, что вы просите. Является ли еврейское слово тем, которое содержит только еврейские символы и пробелы, или это просто слово, которое не содержит латинских символов? В любом случае, вы можете сделать это напрямую. Просто создайте набор критериев и проверьте на членство.

Обратите внимание, что тестирование на членство в наборе происходит намного быстрее, чем итерация через string.ascii_letters.

Обратите внимание, что я не говорю на иврите, поэтому, возможно, я пропустил одну или две буквы алфавита.

def is_hebrew(word):
    hebrew = set("א‎ב‎ג‎ד‎ה‎ו‎ז‎ח‎ט‎י‎כ‎ך‎ל‎מ‎נ‎ס‎  ע‎פ‎צ‎ק‎ר‎ש‎ת‎ם‎ן‎ף‎ץ"+string.whitespace)
    for char in word:
        if char not in hebrew:
            return False
    return True

def contains_latin(word):
    return any(char in set("abcdefghijklmnopqrstuvwxyz") for char in word.lower())
# a generator expression like this is a terser way of expressing the 
# above concept.

hebrew_words = [word for word in words if is_hebrew(word)]
non_latin words = [word for word in words if not contains_latin(word)]

Другой вариант - создать словарь ивритских слов:

hebrew_words = {...}

И затем вы перебираете список слов и сравниваете их с этим регистром игнорирования словаря. Это будет работать намного быстрее, чем другие подходы (O(n), где n - длина вашего списка слов).

Недостатком является то, что вам нужно где-то получить все или большинство еврейских слов. Я думаю, что это можно найти в Интернете в формате CSV или другой форме. Разобрать его и поместить в словарь Python.

Однако имеет смысл, если вам нужно разбирать такие списки слов очень часто и довольно быстро. Другая проблема состоит в том, что словарь может содержать не все еврейские слова, которые не дадут полностью правильный ответ.

Попробуй это:

>>> import re
>>> filter(lambda x: re.match(r'^[^\w]+$',x),s)
Другие вопросы по тегам