RegEx для сопоставления всех символов, кроме некоторых специальных символов и ":)" - PullRequest
7 голосов
/ 11 мая 2019

Я пытаюсь удалить все символы из строки, кроме #, @, :), :(. Пример:

this is, a placeholder text. I wanna remove symbols like ! and ? but keep @ & # & :)

должно привести к (после удаления совпавших результатов):

this is a placeholder text I wanna remove symbols like  and  but keep @  #  :)

Я пытался:

(?! |#|@|:\)|:\()\W

Это работает, но в случае :) и :(, : все еще сопоставляется. Я знаю, что он совпадает, потому что он проверяет каждый символ и предыдущие, например: :) соответствует только :, но :)) соответствует :).

Ответы [ 4 ]

6 голосов
/ 11 мая 2019

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

:)
:(

Чтобы справиться с этим, мы можем сначала сэкономить двоеточие : и скобки, а затем выборочно удалить любой из них, если он не является частью смайлика или хмурого лица:

input = "this is, a (placeholder text). I wanna remove symbols like: ! and ? but keep @ & # & :)"
output = re.sub(r'[^\w\s:()@&#]|:(?![()])|(?<!:)[()]', '', input)
print(output)

this is a placeholder text I wanna remove symbols like  and  but keep @ & # & :)

Я использовал класс символов регулярного выражения:

[^\w\s:()@&#]

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

3 голосов
/ 11 мая 2019

Как показали другие, можно написать регулярное выражение, которое будет успешным, как вы сформулировали проблему. Но это тот случай, когда гораздо проще написать регулярное выражение, соответствующее тому, что вы хотите сохранить . Тогда просто соедините эти части вместе.

import re

rgx = re.compile(r'\w|\s|@|&|#|:\)|:\(')
orig = 'Blah!! Blah.... ### .... #@:):):) @@ Blah! Blah??? :):)#'
new = ''.join(rgx.findall(orig))
print(new)
2 голосов
/ 11 мая 2019

Вы можете попробовать следующее регулярное выражение (для Python).

(\w|:\)|:\(|#|@| )

С этим поддельным предложением:

"Я хочу удалить определенные символы, но хочу сохранить определенные, такие как #random, and :) и :( и что-то вроде @.

Если оно найдено в другом предложении, :), поищите его :( "

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

1 голос
/ 11 мая 2019

Вы также можете использовать простой подход: сопоставить и захватить то, что вам нужно, чтобы «исключить» из сопоставления и просто сопоставить то, что вы хотите удалить, а затем просто использовать обратную ссылку на значение группы захвата:

re.sub(r'([#@\s]|:[)(])|\W', r'\1', s)
#        ^---Group 1--^->->->->^^         

См. Демоверсию regex . Здесь ([#@\s]|:[)(]) соответствует и захватывает в Группу 1 a #, @, пробельные символы или :( или :( подстроки и \W совпадения без захвата любого несловарного символа.

См. Демо Python :

import re
s="this is, a placeholder text. I wanna remove symbols like ! and ? but keep @ & # & :)"
print(re.sub(r'([#@\s]|:[)(])|\W', r'\1', s))
# => this is a placeholder text I wanna remove symbols like  and  but keep @  #  :)

В версиях Python до 3.5 используйте лямбда-выражение в качестве аргумента замены (из-за ошибки):

re.sub(r'([#@\s]|:[)(])|\W', lambda x: x.group(1) if x.group(1) else '', s)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...