Wyrażenie regularne z jedną cyfrą

Wyrażenie regularne z jedną cyfrą
unikalna_nazwa
  • Rejestracja: dni
  • Ostatnio: dni
0

jak napisać wyrażenie regularne (i czy się da w ogóle) żeby szukało 20 liter koło siebie wśród których występują przynajmniej jedna cyfra?

aktualnie mam to zapisane dwoma wyrażeniami, najpierw szukam liter i cyfr a potem sprawdzam czy są jakieś cyfry w wyniku

byku_guzio
  • Rejestracja: dni
  • Ostatnio: dni
0

Możesz to trochę bardziej sprecyzować? Gdzie ma być ta cyfra/cyfry? W środku otoczona z obu stron dwudziestoma literami?

olesio
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Szczecin
  • Postów: 4191
0

@unikalna_nazwa: rozumiem, że coś innego niż to poniżej potrzebujesz:
[A-Z0-9]{20}
Sorry, ale wyrażenia regularne znam tak sobie, a zajrzałem do tego działu przy okazji spojrzenia w inny temat, który zaczął pelsta, więc spojrzałem na ten wątek niejako przy okazji.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

Na moje oko się nie da. Wystarczy pomyśleć jak musiałby wyglądać automat skończony akceptujący takie słowo. Nie da się tak zrobić ze automat zaakceptuje jeśli wystąpiła przynajmniej 1 cyfra - pomijam oczywiście trywialną wersję, tzn ropatrywanie wszystkich przypadków:

Kopiuj
\d[A-Za-z]{19} | [A-Za-z]\d[A-Za-z]{18} | .... [A-Za-z]{19}\d
unikalna_nazwa
  • Rejestracja: dni
  • Ostatnio: dni
0
Shalom napisał(a)

Na moje oko się nie da. Wystarczy pomyśleć jak musiałby wyglądać automat skończony akceptujący takie słowo. Nie da się tak zrobić ze automat zaakceptuje jeśli wystąpiła przynajmniej 1 cyfra - pomijam oczywiście trywialną wersję, tzn ropatrywanie wszystkich przypadków:

Kopiuj
\d[A-Za-z]{19} | [A-Za-z]\d[A-Za-z]{18} | .... [A-Za-z]{19}\d

nom, tak też myślałem, ale miałem nadzieję że może przeoczyłem jakąś składnię regexpa
ogólnie chodzi o przetestowanie wewnątrz wyrażenia tego co już automat znalazł więc nie musiałoby to być takie znowu skomplikowane

w każdym razie dzięki
chyba że ktoś jednak ma pomysł na jakiś sprytny myk :>

byku_guzio
  • Rejestracja: dni
  • Ostatnio: dni
0

Jeżeli to ma byś standardowy regex to tego nie zrobisz tak jak Shalom pisze, ale jeżeli to jest regex z jakiejś biblioteki(np. standardowej javy, .Net czy boost) to może się dać. Przeważnie takie silniki regex'ów obsługują grupy dopasowań i cofanie się w tym co już zostało dopasowane.

RE
  • Rejestracja: dni
  • Ostatnio: dni
1

Tak na moje oko.. (?=\b\w{20}\b)\b[A-Za-z]*\d[A-Za-z]*\b.

unikalna_nazwa
  • Rejestracja: dni
  • Ostatnio: dni
0
Rev napisał(a)

Tak na moje oko.. (?=\b\w{20}\b)\b[A-Za-z]*\d[A-Za-z]*\b.

heh, sprytne
proste, ale sam na trzeźwo bym chyba na to nie wpadł :D
zawsze lookahead jak już to wykorzystywałem na końcu wyrażenia i zapomniałem że może być bardziej przydatne :)

z tym że mała zmiana bo miała być przynajmniej jedna cyfra a nie konkretnie jedna
no i jeszcze problem bo okazało się że muszę to jeszcze rozbudować o warunek że nie mogą być też same cyfry
mój strzał:

Kopiuj
/(?=\b\w{20}\b)\b(\w*?\d\w*?|\w*?[A-Za-z]\w*?)\b/

nie testowałem tego jeszcze - jutro to zrobię bo trochę już późno ;)

pytanie tylko:

czy opłaca się tak rozbudowywać zapytanie brzmiące oryginalnie

Kopiuj
/\b(\w{20})\b/

na rzecz pozbycia się dwóch prostych warunków później?

i pytanie przy okazji, lepiej jest pisać /[A-Za-z]/ czy /[A-Z]/i ?

// aha, zapomniałem - dzięki

byku_guzio
  • Rejestracja: dni
  • Ostatnio: dni
0

To czy się opłaca tak rozbudowywać regexa to trzeba by przetestować jak to wypada z wydajnością. Moim zdaniem nie - czytelność tego jest delikatnie rzecz ujmując kiepska, a wydajnościowo raczej zysku nie będzie(o ile w ogóle straty na tym się nie pojawią).

Co do ostatniego pytania to już raczej kwestia gustu i przyzwyczajenia - specjalnej różnicy to nie robi.

unikalna_nazwa
  • Rejestracja: dni
  • Ostatnio: dni
0

niestety tamten strzał nie zadziałał, bo dopuszczał same cyfry lub same litery - po prostu kiedy tekst przestał pasować do jednego to zaczął do drugiego

przemieniłem to wszystko i doszedłem do wyrażenia:

Kopiuj
/\b(?=\w*?(?:\d[a-z]|[a-z]\d)\w*)\w{20}\b/i

jest IMHO też trochę bardziej czytelny, bo patrząc na to co jest poza lookahead mamy proste wyrażenie \w{20} więc wiadomo co to ma zwrócić ;)
pierwsze testy wyrażenie zdało

akurat nie musi to być super wydajne bo to zapytanie wywołuje się raz i w mało krytycznej miejscu więc wydajność nie ma wielkiego znaczenia
mimo to chyba powróce na rzecz czytelności do warunków programowych

ale i tak fajnie było się pobawić i przypomnić sobie trochę regexpa ;)
pozdr i dzięki

iooi
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 573
0
Kopiuj
\b(?=\w*?(?>\d[a-z]|[a-z]\d)\w*)\w{20}\b

Bo domyślnie quantifier jest tylko zachłanny.

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.