Позитивен и негативен преглед в регулярните изрази на Python
Понякога трябва да решим задача от този тип:
намери низ 'aaa' и го замени
с '!', но само ако след
'aaa' има 'x', като самият
'x' не се заменя. Ако се опитаме
да решим задачата 'директно',
няма да успеем:
txt = 'aaax baaa'
res = re.sub('aaax', '!', txt)
print(res) # ще изведе '! baaa', а искахме '!x baaa'
Поглед напред
За решаване на задачата е необходим начин да се каже,
че 'x' не трябва да се заменя. Това се
прави със специални скоби (?= ),
които само проверяват, но не вземат
част от съвпадението.
Тези скоби се наричат позитивен преглед
напред. Позитивен - защото 'x'
(в нашия случай) трябва да присъства - само тогава
ще се извърши замяната.
Нека приложим тези скоби за решаване на нашата задача:
txt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # ще изведе '!x baaa'
Има и негативен преглед напред
- (?! ) - той, обратно, казва,
че нещо не трябва да присъства. В следващия
пример замяната ще се извърши, само ако
след 'aaa' няма 'x':
txt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)
print(res) # ще изведе 'aaax !b'
Поглед назад
Аналогично има позитивен
преглед назад - (?<= ). В
следващия пример замяната ще се извърши, само
ако преди 'aaa' има 'x':
txt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)
print(res) # ще изведе 'x!'
Има също и негативен преглед назад
- (?<! ). В следващия пример
замяната ще се извърши, само ако преди
'aaa' няма 'x':
txt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)
print(res) # ще изведе 'b!'
Практически задачи
Даден е низ, съдържащ имена на функции:
txt = 'func1() func2() func3()'
Получете масив от имената на функциите от низа.
Даден е низ с таг:
txt = '<a href="" class="eee" id="zzz">'
Получете масив от имената на атрибутите на този таг.
Даден е низ с променливи:
txt = '$aaa $bbb $ccc xxxx'
Получете поднизовете, предшествани от символа долар.