Регулярное выражение для сопоставления строки с подстрокой - PullRequest
1 голос
/ 02 мая 2019

Я ищу решение регулярного выражения для замены подстроки с заданным динамическим шаблоном. Проблема в том, что подстрока может содержать известный токен, и мы не знаем, в какой позиции этот токен находится. Я могу сформулировать проблему следующим образом: Заменить (заданный) шаблон в строке, даже если (известный) токен будет конфликтовать.

Предположим, у нас есть my_string :

Мне нравятся зеленые и PLUS голубые бобы!

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

У нас также есть переменный шаблон под названием my_pattern , который может быть любой частью my_string , за исключением PLUS , такой как:

1) зеленый и синий

2) зеленая и синяя фасоль

3) Мне нравится зеленый

Мы знаем, что PLUS может произойти где-то в my_string , и мы не знаем позицию. Теоретически, my_string также может быть:

I PLUS как зеленые и синие бобы!

Поскольку my_pattern может встречаться в формах 1), 2) или 3), мы также не можем жестко закодировать решение с помощью OR.

Искомое решение: my_string .replace ( my_pattern , "red") с выводом для my_pattern:

1) Я люблю красную фасоль!

2) Мне нравится красный!

3) красная и ПЛЮС голубая фасоль!

my_pattern должны совпадать, хотя PLUS встречается в my_string (что может конфликтовать с my_pattern). Это что-то вроде: сопоставить my_pattern и игнорировать PLUS в случае, если оно мешает совпадению.

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

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

import re
token = 'PLUS'
patterns = ['green and blue', 'green and blue beans', 'I like green']

ptn_pls = [f'( ?{token} ?)?'.join(p) for p in patterns]

Применяется к трем различным строкам:

my_string = 'I like green and PLUS blue beans!'
for p in ptn_pls:
    print(re.sub(p, 'red', my_string))
# I like red beans!
# I like red!                                                 
# red and PLUS blue beans!

my_string = 'I PLUS like green and blue beans!'
for p in ptn_pls:
    print(re.sub(p, 'red', my_string))
# I PLUS like red beans!                                      
# I PLUS like red!                                            
# red and blue beans!  

my_string = 'I like grPLUSeen a PLUSnd blue beans!'
for p in ptn_pls:
    print(re.sub(p, 'red', my_string))
# I like red beans!                                          
# I like red!                                                 
# red a PLUSnd blue beans!     
0 голосов
/ 02 мая 2019

Если ваш токен - слово с пробелами, эта грубая функция может работать:

import re

def skip_token(s, pattern, token, sub):
    p = pattern.split()
    gex = "|".join([pattern] + [" ".join(p[:i] + [token] + p[i:]) for i in range(1, len(p))])
    return re.sub(gex, sub, s)

s = "I like green and PLUS blue beans!"
token = "PLUS"
sub = "red"


>>> print(skip_token(s, "green and blue", token, sub))
>>> print(skip_token(s, "green and blue beans", token, sub))
>>> print(skip_token(s, "I like green", token, sub))

I like red beans!
I like red!
red and PLUS blue beans!

но, если ваша my_string имеет пунктуацию И токен можно найти буквально повсюду, иногда это будет неудачно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...