Найти - Пользователи
Полная версия: Проблема с регулярными выражениями с негативными проверками
Начало » Python для новичков » Проблема с регулярными выражениями с негативными проверками
1 2
artur567297
Здравствуйте столкнулся с проблемой при регулярных выражениях:
В регулярных выражениях есть ретроспективные проверки это ?<= и ?<! и опережающие это ?= и ?!. Они есть положительные и отрицательные. ПОЛОЖИТЕЛЬНЫЕ РАБОТАЮТ ПРАВИЛЬНО А ОТРИЦАТЕЛЬНЫЕ НЕТ.
Позитивная ретроспективная проверка ?<=: (?<=Y)X, ищет совпадение с X при условии, что перед ним ЕСТЬ Y. ЭТА ПРОВЕРКА РАБОТАЕТ НОРМАЛЬНО НА ПРИМЕР: print(re.findall(r'(?<=7)\w+', ‘HISD 7BAS’)) – вернет все что после семерки
Негативная ретроспективная проверка ?<!: (?<!Y)X, ищет совпадение с X при условии, что перед ним НЕТ Y. ЭТА ПРОВЕРКА РАБОТАЕТ НЕ ПРАВИЛЬНО НА ПРИМЕР: print(re.findall(r'(?<!7)\w+', ‘HISD 7BAS’)) – должна вернуть по сути слово HISD а возвращается полностью выражение HISD 7BAS – ПРИЧЕМ В javascript этот код отрабатывает правильно, проблема только в питоне.
Позитивная опережающая проверка ?=: X(?=Y) ишет X при условии что за ним следует Y. ЭТА ПРОВЕРКА РАБОТАЕТ ПРАВИЛЬНО НА ПРИМЕР: print(re.findall(r'\w+\s(?=one)', ‘zet ru is one to be ’)) – вернет только слово ‘is’ как и должно быть.
Негативная опережающая проверка ?!: X(?!Y) ищет X за которым НЕ следует Y. ЭТА ПРОВЕРКА РАБОТАЕТ НЕ ПРАВИЛЬНО НА ПРИМЕР: print(re.findall(r'\w+\s(?!one)', ‘zet ru is one to ’)) – вернет ‘zet ’, ‘ru ’, ‘one ’, ‘to ’ – ‘is’ не возвращается как и должно быть: НО ПОЧЕМУ ВОЗВРАШАЕТСЯ ‘one’ ОНО ВЕДЬ НЕ ДОЛЖНО ВЕРНУТЬСЯ В РЕЗУЛЬТАТ?
py.user.next
artur567297
РАБОТАЕТ НЕ ПРАВИЛЬНО НА ПРИМЕР: print(re.findall(r'(?<!7)\w+', ‘HISD 7BAS’)) – должна вернуть по сути слово HISD а возвращается полностью выражение HISD 7BAS
Она не возвращает полностью пыражение HISD 7BAS, как ты пишешь, потому что пробел не может входить в класс символов \w. Ты хоть научись сначала выводить всё правильно и точно.

Смотри, как это делается
  
>>> import re
>>> 
>>> re.findall(r'(?<!7)\w+', 'HISD 7BAS')
['HISD', '7BAS']
>>>
Ты просто не знаешь, как работает функция re.findall().

А чтобы знать, сначал прочитай вот это вот всё
https://docs.python.org/3/library/re.html

А потом уже приходи со своими умными идеями, написанными капслоком. Тебя ещё никогда нигде не банили за капслок не по делу? Скоро забанят, так что не обижайся потом.

artur567297
ПРИЧЕМ В javascript этот код отрабатывает правильно, проблема только в питоне.
Какой код в JavaScript отрабатывает правильно? Там такой функции нет даже.

artur567297
ЭТА ПРОВЕРКА РАБОТАЕТ ПРАВИЛЬНО НА ПРИМЕР: print(re.findall(r'\w+\s(?=one)', ‘zet ru is one to be ’)) – вернет только слово ‘is’ как и должно быть.
Она не возвращает is, а возвращает is с пробелом. У тебя опять что-то не высветилось и ты даже не понимаешь, что именно выводится на экран.

Смотри, как это делается
  
>>> import re
>>> 
>>> re.findall(r'\w+\s(?=one)', 'zet ru is one to be ')
['is ']
>>>

artur567297
Негативная опережающая проверка ?!: X(?!Y) ищет X за которым НЕ следует Y. ЭТА ПРОВЕРКА РАБОТАЕТ НЕ ПРАВИЛЬНО НА ПРИМЕР: print(re.findall(r'\w+\s(?!one)', ‘zet ru is one to ’)) – вернет ‘zet ’, ‘ru ’, ‘one ’, ‘to ’ – ‘is’ не возвращается как и должно быть: НО ПОЧЕМУ ВОЗВРАШАЕТСЯ ‘one’ ОНО ВЕДЬ НЕ ДОЛЖНО ВЕРНУТЬСЯ В РЕЗУЛЬТАТ?

Ну, возвращается всё правильно
  
>>> import re
>>> 
>>> re.findall(r'\w+\s(?!one)', 'zet ru is one to ')
['zet ', 'ru ', 'one ', 'to ']
>>>

А one возвращается потому, что это функция re.findall(). Так как последовательность символов one находится в подсматривающей группе, то она не учитывается как совпадение, поэтому и не возвращается функцией re.findall() в качестве чего-то найденного. А так как последовательность символов one не обозначена в качестве найденной или в которой вообще был поиск, то по ней следующий поиск начинается функцией re.findall(), потому что эта функция так работает. Когда функция re.findall() нашла что-то и вернула это или нашла и не вернула (как в данном случае), следующий поиск она продолжает с того места, где закончилось найденное и возвращённое или найденное и невозвращённое (как в данном случае) из неё значение. Если она следующий после is поиск начинает с one, то после one нет никакого второго one, поэтому она его и возвращает. Вот и всё.

Если ты говоришь, что прямая ищет без повторных поисков по one, то ничего подобного
  
>>> import re
>>> 
>>> re.findall(r'\w+\s(?=one)', 'one one one one')
['one ', 'one ', 'one ']
>>>
Всё так же работает.
artur567297
py.user.next

re.findall(r'\w+\s(?!one)', ‘zet ru is one to ’) - здесь все понятно - вопрос снят.

Но вопрос по re.findall(r'(?<!7)\w+', ‘HISD 7BAS’) - должно вернуться только ‘HISD’ так как выражение
(?<!Y)X, ищет совпадение с X при условии, что перед ним нет Y то есть Y = 7 а семерки нет только перед словом ‘HISD’ поэтому его только должно и вернуть но возврашается ‘HISD’, ‘7BAS’
py.user.next
artur567297
Но вопрос по re.findall(r'(?<!7)\w+', ‘HISD 7BAS’) - должно вернуться только ‘HISD’ так как выражение
(?<!Y)X, ищет совпадение с X при условии, что перед ним нет Y то есть Y = 7 а семерки нет только перед словом ‘HISD’ поэтому его только должно и вернуть но возврашается ‘HISD’, ‘7BAS’

Возвращает всё правильно
  
>>> import re
>>> 
>>> re.findall(r'(?<!7)\w+', 'HISD 7BAS')
['HISD', '7BAS']
>>>
Перед словом 7BAS стоит пробел. Пробел - это символ такой, и он не семёрка.

Если бы ты прочитал ту ссылку, которую я тебе дал выше, то ты бы там нашёл описание класса символов \w , в котором написано, какие символы в него входят.
artur567297
py.user.next
так и так не помогает:
re.findall(r'(?<!\s7)\w+', ‘HISD 7BAS’)
все равно возврашается ‘HISD’, ‘7BAS’
получается что с помошью символа ?<!7 нельзя вернуть слова которые не начинаются на 7?
Рабочий код в JS let str = “HISD 7BAS”;
console.log(str.match(/(?<!7)\w+/) ); - возврашает только HISD

ВЕДЬ СУТЬ РЕГУЛЯРНЫХ ВЫРАЖЕНИЙ ОДНА ВО ВСЕХ ЯЗЫКАХ?
py.user.next
artur567297
Рабочий код в JS let str = “HISD 7BAS”;
console.log(str.match(/(?<!7)\w+/) ); - возврашает только HISD

В JavaScript метод match() у строки возвращает только первое найденное вхождение, если не указан флаг g
  
-> "HISD BAS".match(/\w+/)
<- Array ["HISD"]
  
-> "HISD 7BAS".match(/(?<!7)\w+/g)
<- Array [ "HISD", "7BAS" ]

В Python функция re.findall() возвращает все вхождения.

Ты читать по-английски не умеешь? Это же всё описано в документации и к JavaScript (ECMAScript), и к Python. Да, переводов нет, но так и программирование - это международное дело. Если тебе по-русски только надо, то займись компьютером Электроника, у которого вместо флешек кассеты с плёнкой, и вообще забудь про Интернет, он русским никогда не был.
artur567297
py.user.next
В Python функция re.findall() возвращает все вхождения.
В Python функция re.findall() возвращает все вхождения. - так какие вхождения если шаблон (?<!Y)X, ищет совпадение с X при условии, что перед ним нет Y а Y = 7 или Y = \s7 а значит вернуть 7BAS не должен или как???
py.user.next
artur567297
что перед ним нет Y а Y = 7 или Y = \s7 а значит вернуть 7BAS не должен или как?
Да, если перед ним нет, ну и перед 7BAS нет семёрки. Там пробел перед 7BAS. А пробел это символ такой. И пробел - это не семёрка.
artur567297
py.user.next
Там пробел перед 7BAS.
Там пробел перед 7BAS. - так я могу поставить Y = \s7 все равно вернет 7BAS
ZerG
artur567297
HISD 7BAS
Тебе нужно ити в противотанковые войска - любую броню продавишь пальцем
Тебе py.user.next два раза обьяснил что в джысы и и питоне разные методы обрабатывают рагулярки и потому разные результаты

С другой стороны чего еще ждать если вместо того что бы почитать ссылку ты продолжаешь угадывать а не думать
 import re
st = "HISD 7BAS 7HUYAS"
pattern = r'\b[^\W7]+\b'
matches = re.findall(pattern, st)
print(matches)
["HIDS"]
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB