Regex объединяет слова, разделенные пробелом и дефисом - PullRequest
0 голосов
/ 28 января 2019

Моя строка довольно грязная и выглядит примерно так:

s="I'm hope-less and can -not solve this pro- blem on my own. Wo - uld you help me?"

Я бы хотел, чтобы дефис (и иногда пробел) отбрасывал слова вместе в одном списке ...Желаемый результат:

list = ['I'm','hopeless','and','cannot','solve','this','problem','on','my','own','.','Would','you','help','me','?']

Я пробовал много разных вариантов, но ничего не получалось ..

rgx = re.compile("([\w][\w'][\w\-]*\w)") s = "My string'" rgx.findall(s)

Ответы [ 3 ]

0 голосов
/ 28 января 2019

Вот один из способов:

[re.sub(r'\s*-\s*', '', i) for i in re.split(r'(?<!-)\s(?!-)', s)]

# ["I'm", 'hopeless', 'and', 'cannot', 'solve', 'this', 'problem', 'on', 'my', 'own.', 'Would', 'you', 'help', 'me?']

Здесь две операции:

  1. Разделить текст на основе пробелов без дефисов , используя оба отрицательных взглядаи отрицательный взгляд сзади.

  2. В каждом из разделенных слов замените дефисы возможными пробелами спереди или сзади на пустую строку.

ВыЗдесь вы можете увидеть демонстрацию первой операции: https://regex101.com/r/ayHPvY/2

И вторая: https://regex101.com/r/ayHPvY/1

Редактировать: чтобы разделить . и ?, используйте этовместо этого:

[re.sub(r'\s*-\s*','', i) for i in re.split(r"(?<!-)\s(?!-)|([^\w\s'-]+)", s) if i]

# ["I'm", 'hopeless', 'and', 'cannot', 'solve', 'this', 'problem', 'on', 'my', 'own', '.', 'Would', 'you', 'help', 'me', '?']

Улов также разделял не алфавиты, не пробелы, а не дефисы / апострофы.if i необходим, так как разделение может вернуть некоторые None элементов.

0 голосов
/ 28 января 2019

Как насчет этого:

>>> s
"I'm hope-less and can -not solve this pro- blem on my own. Wo - uld you help me
?"
>>> list(map(lambda x:re.sub(' *- *','',x), filter(lambda x:x, re.split(r'(?<!-) +(?!-)|([.?])',s))))
["I'm", 'hopeless', 'and', 'cannot', 'solve', 'this', 'problem', 'on', 'my', 'own', '.', 'Would', 'you', 'help', 'me', '?']

Выше использовался простой пробел ' ', но лучше использовать \s:

list(map(lambda x:re.sub('\s*-\s*','',x), filter(lambda x:x, re.split(r'(?<!-)\s+(?!-)|([.?])',s))))

(?<!-)\s+(?!-) означает пробелы, которые не- до или после.
[.?] означает один . или ?.

re.split(r'(?<!-)\s+(?!-)|([.?])',s) соответственно разделит строку, но будет содержать None и пустую строку '' внутри:

["I'm", None, 'hope-less', None, 'and', None, 'can -not', None, 'solve', None, 'this', None, 'pro- blem', None, 'on', None, 'my', None, 'own', '.', '', None, 'Wo - uld', None, 'you', None, 'help', None, 'me', '?', '']

Этот результат был напрямую передан в filter для удаленияNone и '', а затем введите map для удаления пробела и - внутри каждого слова.

0 голосов
/ 28 января 2019

Быстрый способ сделать это без регулярного выражения:

''.join(map(lambda s: s.strip(), s.split('-'))).split()

, который разделен на дефисы, полоса дополнительных пробелов, соединен обратно в строку и разделен на пробел, однако это не разделяет точкуили вопросительные знаки.

...