Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Regex - różna kolejność cyfr
Forum PHP.pl > Forum > PHP
bigmac72
Cześć.

Panowie. Mała prośba o pomoc.
Nie jestem wyjadaczem jeżeli chodzi o wyrażenia, a potrzebowałbym napisać patterna.
Wiem, że można to zrobić za pomocą funkcji, ale jestem przekonany, że wzorzec też się jakiś uda ułożyć.
Do rzeczy.

Mam liczbę całkowitą składającą się z 4 cyfr np. 1234.
Po przekształceniu ta cyfra może być 2341 lub 4231 lub 1423 itd.
Potrzebuję wyrażenie, które będzie zgodne z tymi cyframi.
Innymi słowami, muszą być te same cyfry ale w różnej kolejności.
Mogę mieć cyfrę 1123 a po przekształceniu 1231 i wyrażenie musi być zgodne.

Wzorzec będzie budowany dynamicznie dla każdej cyfry.
np dla cyfry 1234 wzorzec będzie [1234]{4} lub ([1{1,4},2{1,4},3{1,4},4{1,4}]){4} - to oczywiście błędny wzorzec.

Będę zobowiązany za pomoc w temacie.

!*!
Cytat
'/^[1-4]/'
abort
!*!, prawie dobrze - Twoje zmatchuje JEDNĄ cyfrę.
Kod
'/^[1-4]{4}/'

cudny
Wyrażenia są prawidłowe o ile te cyfry będą kolejne !

Czy te cyfry to od 1 do 4 czy jednak może być 2759 i też ważne pytanie, czy wcześniej znasz te cyfry ?
bigmac72


Liczby będą w zakresie od 1000 do 9999, nie będą znane. Są generowane automatycznie.
Dla każdej wygenerowanej losowo liczby będę potrzebował regexa, który będzie pasował do tych cyfr, ale 'wymieszanych'.
Np cyfry 2759 mogą być cyfry 9752 albo 7295 albo 5729 itd.
Regex będę generował automatycznie dla każdej wygenerowanej cyfry.
Crozin
Tutaj w ogóle nie ma potrzeby użycia wyrażeń regularny. Wystarczy obie liczby (Twoją i nadesłaną przez użytkownika) potraktować jako tablicę znaków (str_split), posortować ją (sort), złączyć całość w jeden ciąg (implode) i na końcu porównać czy obie wartości są takie same.
bigmac72
Crozin dzięki za odpowiedz, ale chcę uniknąć używania algorytmów.

Może jeszcze jakiś pomysł na regexa ?
!*!
Padło już.

Cytat
'/(^[0-9]{4})$/'


Skoro ma być to zakres od 0 do 9, w ilości sztuk 4.
viking
W zasadzie to od 1000.
Cytat
([1-9][0-9]{3}){4}

Czy jakoś tak, nie sprawdzam.
Crozin
Cytat
Crozin dzięki za odpowiedz, ale chcę uniknąć używania algorytmów.
No to zadanie jest niemożliwe do wykonania, a już na pewno nie przy użyciu wyrażeń regularnych, które wykorzystują niezwykle skomplikowane algorytmy (porównując do tego co podałem). Na dobrą sprawę wszystko co chcesz zrobić, to sprawdzić czy oba ciągi są anagramami samych siebie. Osiągnięcie tego przy użyciu wyrażeń będzie trudne, a na pewno niezwykle nieczytelne.

@!*!: Nie chodzi o sprawdzenie czy ciąg jest liczbą składającą się z cyfr 0-9, tylko czy wykorzystuje wszystkie cyfry z oryginalnej liczby.
!*!
Cytat(Crozin @ 28.09.2012, 12:30:20 ) *
@!*!: Nie chodzi o sprawdzenie czy ciąg jest liczbą składającą się z cyfr 0-9, tylko czy wykorzystuje wszystkie cyfry z oryginalnej liczby.


Fakt. A nie możesz po prostu zamiast 0-9 dać tych cyfr w wyrażeniu?

  1. '/^[5317]{4}$/'

  1. '/^['.$toCoGenerujeszWczesniej.']{4}$/';

bigmac72
Panowie, dobrze kombinujecie, ale to jeszcze nie to.
Przykład:

cyfra: 1234 i regex: [1234]{4}

jakie wartości będą prawidłowe ?

1234, 2341 itd - ale też 1111, 2222, 3333, 4444

o co mi chodzi ? o to żeby wymusić wszystkie cyfry a [1234] nie wymusza,

możemy wymusić wszystkie elementy [1{1}2{1}3{1}4{1}]{4} - takim wzorcem, ale on wymusza również kolejność elementów - a ja potrzebuję różną kolejność.

i jeszcze raz napiszę - dla każdej cyfry będę generował wzorzec.
potrzebuję tylko sprawdzić czy cyfra, która mi wchodzi do metody, spełnia warunek.

wiem, że to nie łatwy problem, dlatego postanowiłem założyć wątek, poprostu nie znalazłem odpowiedzi, albo nie wiem jak szukać, więc proszę o podpowiedzi
Crozin
Ale wiesz, że dostałeś już właściwie odpowiedź podaną na tacy, a Ty dalej brniesz w te wyrażenia, które się tutaj kompletnie nie nadają (ciąg od użytkownika nie ma regularnej struktury).
BaN
@Crozin ma rację. Dodatkowo aby zbudować wzorzec dla wyrażenia regularnego i tak musiałbyś zastosować algorytm, który uwzględnia anagramy danego ciągu, zupełnie bez sensu stosować wtedy wyrażenie regularne.
Do jego algorytmu w poście #6 tylko można dorzucić na samym początku sprawdzanie czy łańcuchy mają równą długość, jeśli nie, to nie ma sensu dalej przekształcać
Ewentualnie trochę inny algorytm z usuwaniem znaków:
  1. function check_str($pattern, $str) {
  2. if (strlen($pattern) != strlen($str)) {
  3. return false;
  4. }
  5. foreach (str_split($pattern) as $v) {
  6. $pos = strpos($str, $v);
  7. if ($pos !== false) {
  8. $str = substr_replace($str, '', $pos, 1);
  9. }
  10. }
  11. return (strlen($str) == 0);
  12. }



bigmac72
Dzięki panowie za odpowiedzi.
Algorytm mam już działający. Szukałem innego rozwiązania.
Pozdrawiam i dzięki za poświęcenie czasu na odpowiedz.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.