Wyrażenia regularne, problem ze wzorcem

Wyrażenia regularne, problem ze wzorcem
KD
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:53
0

Eksperymentuję trochę z wyrażeniami regularnymi w Pythonie i opracowałem taki wzorzec:
\d{2}(?=60)/b

Dziwi mnie bardzo czemu nie działa na:

Kopiuj
606050 605038 601492
405060 606060 602603

jak dla mnie powinien zaznaczyć:

606050 605038 601492
405060 606060 602603

Co źle rozkminiłem? :(
Reszta wzorców dla reszty konstrukcji przewidywania działa poprawnie.


Niech wiek nie ogranicza chęci poszerzenia horyzontów!
edytowany 3x, ostatnio: KaDwa
99xmarcin
/b ->\b może to???
KD
Dzięki za czujność, mój błąd przy przepisywaniu. To nie jest to :(
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0

Do czego jest to b? Bo /b nic nie znaczy, a \b nie ma sensu, jeśli chcesz uzyskać rezultat, jak na przykładzie.

\d{2}(?=60) zaznacza, to co wskazałeś, a nawet więcej https://regexr.com/

Może napisz najpierw, jaki efekt chcesz uzyskać, bo bez tego trudno cokolwiek radzić :)


99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:6 miesięcy
  • Postów:2420
1

\b to od word boundary.

\d{2}(?=60\b) powinno działać. W sumie jak jest lookahead to również boundary jest lookahead'owane.


Holy sh*t, with every month serenityos.org gets better & better...
KD
KD
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:53
0

@0xmarcin:
Ma to sens, zwłaszcza że działa. Wydawało mi się, że moje też powinno działać, dużo jeszcze przede mną.

Pomożesz mi jeszcze to ogarnąć:
(?!60)\d{2}\b
606050 605038 601492
405060 606060 602603

Czemu tu działa: 606050 ?


Niech wiek nie ogranicza chęci poszerzenia horyzontów!
edytowany 2x, ostatnio: KaDwa
99xmarcin
Bo lookahead działa tak że jak jesteś w miejscu X to po prostu patrzy czy następna fraza to 60 nie przesuwając przy tym pozycji, w twoim przypadku następna fraza to 50 czyli działa :D
99xmarcin
Jakbyś miał 606060 to by odrzuciło bo byś miał w lookahead 60.
99xmarcin
Nie wiem czy zrozumiałeś te tłumaczenia więc jeszcze przykład w 606050 regex zacznie maczować (znacznik . - poz w tekscie): 6060.50. 1) lookahead - nie może być 60 - sprawdzmy - przed nami jest 50 więc jest ok. 2) mają być 2 liczby, sprawdźmy - ok mamy przed sobą 50, zjadamy obie liczby i teraz jest 606050. 3) ma być granica słowa, ok jest 4) koniec wyrażenia więc mamy pełny match
99xmarcin
To czego można użyć to negative lookbehind, (?<!60)\d{2}\b - nie wiem czy takie zaawansowane regexy to dobry pomysł, na pewno warto dodać komentarz i link do doc'a: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions
KD
Zgadza się, zaproponowany nowy przez Ciebie wzorzec testowałem wcześniej i robi to zrozumiale (efekt jest zgodny z oczekiwanym). Przedstawione maczowanie nie wyjaśniło mi wyniku, bo powinno być zaznaczone 60 w 405060. Bo ja to rozumuję tak, w uproszczeniu: od granicy na końcu słowa weź 4 znaki, jeśli 2 pierwsze nie są "60" to interesują mnie 2 kolejne (czyli ostatnie). Może jaśniejsze moje rozumowanie jest przy wzorcu: `\b(?!un)\w+\b' np. mówi daj mi wszystkie słowa które nie rozpoczynają się na "un". Nie będą zaawansowane jak je poznam :) Jak się uda.
KD
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:53
0

Zaczęło mnie zastanawiać jedno, gdy zaproponowałeś poprawiony wzorzec (?<!60)\d{2}\b to dochodzę do wniosku, że źle stworzyłem wzorzec i zły dobrałem przykład. Chodzi głównie o zasadę wyszukiwania, kolejność we wzorcu. Zaraz wyedytuję i pokaże podsumowanie :)

Ja to widzę tak dla słów:

Kopiuj
xy  xz  yx  zx

przy wzorcu: x(?=y)
znajduje x tylko wtedy gdy po x jest y
xy xz yx zx

przy wzorcu: x(?!y)
znajduje x tylko wtedy gdy po x nie ma y
xy xz yx zx

Błędny wzorzec: (?!y)x bo to jest to samo co wzorzec: x i da w efekcie: xy xz yx zx

przy wzorcu: (?<=y)x
znajduje x tylko wtedy gdy zaraz przed x jest y
xy xz yx zx

przy wzorcu: (?<!y)x
znajduje x tylko wtedy gdy przed x nie ma y
xy xz yx zx
dwa pierwsze x nie mają y przed sobą, zatem też pasują do wzorca. Można tu obarczyć prostotę przykładu, ale pokazuje słabości przed którymi trzeba się zabezpieczyć. Ja zakładam, że interesuje mnie koniec słowa i chce osiągnąć taki efekt: xy xz yx zx więc należy:
poprawić wzorzec na: (?<!y)x\b

Błędny wzorzec: x(?!y) bo to jest to samo co wzorzec: x i da w efekcie: xy xz yx zx

Czy to wszystko jest przydatne, jak zakładam że warto to znać bo wyrażeniami regularnymi można dużo i szybko osiągnąć (choć mało jeszcze wiem). Tak na szybko szukając zastosowanie dla przewidywania to zamiast wyszukiwać dopasowania ze zbędnym tekstem można użyć wzorca: (?<=href=\").*(?=:) i wyciągnąć sam rodzaj protokołu <a class="link" href="https://takiadres.pl/</a>

Dodając do aseracji jeszcze alternatywę będzie dopiero można zaszaleć :D Ciekawe czy można połączyć przewidywania z konstrukcją grupowania wstecznego?


Niech wiek nie ogranicza chęci poszerzenia horyzontów!
edytowany 10x, ostatnio: KaDwa

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.