Czy ktoś mógłby mi pomóc w stworzeniu wyrażenia regularnego, które będzie pasowało do zakresu liczb bez pierwszej cyfry z zakresu. Problem wygląda mniej więcej tak:

([1-9]) kilka innych metaznaków [\1-9]

Jak mogę dopasować cyfrę z zakresu nie zawierającego numeru przechowywanego w \1?

PRZYKŁAD: Chciałbym znaleźć liczby zgodne z regułą XZ0XYYXZ000X, gdzie X, Y i Z są liczbami od 1 do 9 (0 < x < Y < Z).

PRZYKŁAD2: Mam plik, który zawiera wiele linii z losowymi liczbami:

2720337
3730447
1362874
itp.

Teraz chcę wyodrębnić te wiersze (na przykład za pomocą grep), które spełniają określone kryteria (na przykład liczby 2720337 i 3730447 spełniają kryteria XZX0YYZ, gdzie X, Y i Z są liczbami od 1 do 9 w następującej relacji X < Y < Z i 0 jest zerem). Mój połów był podobny do tego ([1-9])([\1-9])\1(0)([\1-\2])\3\2, ale nie mogę znaleźć sposobu na pominięcie największej i najniższej wartości z zakresu [\1-\2] lub najniższej z [\1-9]

0
d3ky 23 czerwiec 2011, 21:42
Powinieneś podać przynajmniej jeden przykład danych wejściowych (więcej, tym lepiej) i jaką dokładnie część chcesz przechwycić. (edytuj to w swoim pytaniu)
 – 
kapa
23 czerwiec 2011, 21:45
Podaj przykład, którego nie mogę rozszyfrować, co próbujesz powiedzieć.
 – 
Karoly Horvath
23 czerwiec 2011, 21:45
Czy możesz podać konkretny wkład, a następnie oczekiwany wynik z tego konkretnego wkładu?
 – 
NorthGuard
23 czerwiec 2011, 22:09
1
Myślę, że rozumiem, czego chcesz. Ale jeśli dobrze rozumiem, jest to dość tajemnicze i nie nadaje się do tego wyrażenie regularne.
 – 
Leif
23 czerwiec 2011, 22:15
Podziel liczbę i zrób trochę matematyki. REGEX nie nadaje się do obliczenia tego: Find XZ0XYYXZ000X, Where 0 < X < Y < Z
 – 
ssapkota
23 czerwiec 2011, 22:27

3 odpowiedzi

Najlepsza odpowiedź

To wyrażenie regularne wymusza unikalność X, Y i Z:

([1-9])((?!\1)[1-9])\10((?!\1|\2)[1-9])\3\2

...ale nie ma możliwości wymuszenia ich kolejności za pomocą wyrażenia regularnego.


O REGEX:

([1-9]) przechwytuje pierwszą cyfrę w grupie #1. To pierwszy X w Twoim szablonie.

((?!\1)[1-9]) przechwytuje drugą cyfrę w grupie nr 2, ale dopiero po tym, jak negatywny lookahead potwierdzi, że nie jest to to samo co pierwsza cyfra. To jest wartość Z.

\1 pasuje do trzeciej cyfry, zakładając, że jest taka sama jak pierwsza cyfra.

0 jest oczywiste

((?!\1|\2)[1-9]) reprezentuje wartość Y, więc musimy potwierdzić, że nie jest to to samo, co którekolwiek z pozostałych dwóch przechwyceń. Jest uchwycony w grupie #3.

\3 ponownie dopasowuje tę samą cyfrę; to jest drugi Y.

\2 pasuje do innej wartości Z, a Bob jest twoim wujem!

Wracając jeszcze raz do 0, jest jedno zastrzeżenie, które przeoczyłem. Jeśli w wyrażeniu regularnym jest dziesięć lub więcej grup przechwytywania, \10 może być zinterpretowane jako odwołanie wsteczne do grupy #10. Dobrym pomysłem jest rozbijanie tego typu rzeczy, czy tego potrzebuje, czy nie.

Wiele smaków wyrażeń regularnych zapewnia alternatywną notację, która izoluje odwołanie do grupy, na przykład \g<1> lub ${1}. Nie wiedząc, jakiego smaku używasz, użyję nawiasów kwadratowych, aby wyizolować zero (tj. Zamienię je w jednoelementową klasę znaków):

([1-9])((?!\1)[1-9])\1[0]((?!\1|\2)[1-9])\3\2
1
Alan Moore 24 czerwiec 2011, 03:26
OK, niepowtarzalność X, Y i Z może wystarczyć, zamawianie można wykonać na zewnątrz... ale czy mógłbyś wyjaśnić bardziej szczegółowo swój kod, nie znam niektórych części składni... Pytam o to, bo muszę zaimplementować inne rodzaje wzorca XYY0ZZY, X0Y0ZZZ itp. Wielkie dzięki
 – 
d3ky
24 czerwiec 2011, 00:06
@d3ky: oto twoje wyjaśnienie.
 – 
Alan Moore
24 czerwiec 2011, 03:27
Dzięki Alan, to może być rozwiązanie mojego problemu. Zrobię "zamawianie" gdzieś na zewnątrz.
 – 
d3ky
24 czerwiec 2011, 11:17

Założę, że pasujesz do ciągu XY, gdzie 0 < X < Y <= 9. Możesz łatwo rozszerzyć go do swojego wymagania.

Niestety, nie jest możliwe użycie referencji wstecznych w klasie znaków. Jedynym sposobem, jaki znam, aby to zrobić, jest wyraźne zapisanie wielkości liter dla każdej wartości X: 1[2-9]|2[3-9]|3[4-9]|4[5-9]|5[6-9]|6[7-9]|7[89]|89.

Możliwe byłoby (np. użycie negatywnego wyprzedzenia) upewnienie się, że Y nie równa się X, jak w: ([1-9])(?!\1)[1-9], ale to nie upewnij się, że Y jest nie mniejsze niż X.

0
ahven 23 czerwiec 2011, 22:39
Jeśli mógłbyś wyjaśnić, w jaki sposób mogę odróżnić X, Y i Z za pomocą struktury, o której wspomniałeś (([1-9])(?!\1)[1-9]), może mogę zrobić to samo sortowanie na zewnątrz... Mimo wszystko dziękuję.
 – 
d3ky
24 czerwiec 2011, 00:25

Ok, spróbujmy... w końcu. Jeśli twój drugi przykład oznacza, że ​​liczby mają ten sam wzór, biorąc pod uwagę ich właściwości tej samej cyfry w miejscu, możesz przynajmniej użyć wyrażenia regularnego, aby najpierw to sprawdzić:

([1-9])([1-9])(\1)0([1-9])\4\2

To będzie pasować do 2720337 i 3730447.

Wyrażenie regularne obejmuje niektóre części. Sprawdź, czy 1 USD < 4 USD i 4 USD < 2 USD i gotowe. Jeśli dobrze cię zrozumiałem, to znaczy.

0
Leif 23 czerwiec 2011, 22:59
Niestety istnieje wiele różnych wzorów. Twoja sugestia jest OK dla tego konkretnego wzoru XZX0YYZ, ale co na przykład XYXYZ0Z...
 – 
d3ky
24 czerwiec 2011, 00:30