Wyrażenie regularne z jedną cyfrą

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

0

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

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.

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:

\d[A-Za-z]{19} | [A-Za-z]\d[A-Za-z]{18} | .... [A-Za-z]{19}\d
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:

\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 :>

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.

1

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

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ł:

/(?=\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

/\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

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.

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:

/\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

0
\b(?=\w*?(?>\d[a-z]|[a-z]\d)\w*)\w{20}\b

Bo domyślnie quantifier jest tylko zachłanny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1