[Wyrażenie regularne] Koniec wyrazu

2010-12-09 10:10
Moderator

Rejestracja: 9 lat temu

Ostatnio: 13 godzin temu

0

Mam nadzieję, że pomożecie mi rozkminić jak to zrobić - potrzebne mi wyrażenie regularne, które dopasuje:

[dodatek D]
[dodatek d].
[dodatek d],

ale nie dopasuje:

[dodatek d]odatkowy

Oczywiśćie to mogę być też inne litery. No i jest problem - bo chcę, żeby D było na końcu wyrazu - ale znacznik ">" tu odpada, bo jeśli jest kropka na końcu wyrazu, to już nie podejdzie... Z drugiej strony, jeśli dodam lub kropka na końcu, to zaznaczy mi tą kropkę, a tego też nie chcę... Jak do tego podejść?

Pozostało 580 znaków

Bury pajac
2010-12-09 22:37
Bury pajac
0

Nie całkiem rozumiem na czym polega problem.

Czy to ma być coś takiego że na wejściu masz ciąg "blablabla[dodatek d], blabla" ma zwrócić "[dodatek d]", natomiast sam dodatek ma być formatu [dodatek <tutaj jakaś pojedyńcza litera>]<kropka, przecinek bądź whitespace, ale nie litera, cyfra ...>?

Daj najlepiej kilka przykładów(im więcej, tym lepiej), razem z przypadkami brzegowymi. Łatwiej będzie zrozumieć jak będzie miało format <co na wejściu> ==> <co na wyjściu>.

A jak zależy na czasie to wrzuć swoją fotę na zachętę, najlepiej z roznegliżowaną zawartością.

Pozostało 580 znaków

2010-12-09 23:25

Rejestracja: 10 lat temu

Ostatnio: 7 lat temu

0

@aurel:
Napisz proszę to ściślej, podając kilka przykładów np. w poniższy sposób.

Dla ciągu wejściowego:

coś tamdodatek d,

Ma zostać dopasowane:

dodatek d

Podaj kilka przykładów w ten sposób. NIE wstawiaj tam żadnych zbędnych nawiasów prostokątnych ani innych znaczników, nie występujących w rzeczywistych ciągach i dopasowaniach. Jeśli chcesz zaznaczyć np. fragmenty tekstu za pomocą nawiasów lub jakichkolwiek innych meta-znaków wykorzystywanych na potrzeby posta, to wyraźnie to zaznacz i koniecznie zdefiniuj, że np. te nawiasy prostokątne (tj. znaki ] oraz [) to tylko ograniczniki i pokazują COŚ_TAM, a nie ma ich w ciągach. A najlepiej to nie stosuj takich meta-znaków i napisz to tak, jak ja wyżej.

Bo teraz to nie wiem, czy te nawiasy prostokątne to część ciągu, który masz mieć na wejściu i który ma być dopasowany, czy tylko tak sobie ich używasz żeby nam zaznaczyć gdzie jest dopasowanie. A może one pokazują opcjonalną część ciągu? Cholera wie: tak czy siak, koniecznie to zdefiniuj.

Alternatywnie napisz explicite, że przykłady zapisujesz w formacie CIĄG_WEJŚCIOWY ==> DOPASOWANY_PODCIĄG, przy czym po prawej może się znaleźć tekst [brak dopasowania] oznaczający, że ciąg wejściowy w ogóle nie ma być dopasowany:

dodadek D, foo bar ==> dodatek D
foo dodatek d bar ==> dodatek d
foo dodatek dodatek ==> [brak dopasowania]

Gdy opisujemy ścisłe operacje na tekście, to trzeba wszystko ściśle definiować, bo łatwo się pogubimy ;)

PS. Aha: powinnaś też -- niestety! -- napisać, jakich regexpów używasz. Z .NET-u? Z PHP (które?)? JavaScriptu? Odmiany wyrażeń regularnych różnią się niektórymi szczegółami i jeśli masz bardziej skomplikowany problem, to różnice mogą się uwidocznić (generalnie chodzi o to, że nie wszędzie wszystko jest wspierane).

edytowany 4x, ostatnio: bswierczynski, 2010-12-09 23:35

Pozostało 580 znaków

j_s_r_n
2010-12-10 10:23
j_s_r_n
0

Czy dobrze rozumiem, że szukamy [dodatek d] w ramach normalnego języka pisanego?
Czyli:
[dodatek d]
[dodatek d],
[dodatek d].
itp są prawidłowe, ale już
[dodatek d].2 nie
szukamy więc:
[dodatek d] z opcjonalną grupą 2(3) znaków: znak interpunkcyjny z jakiejś zdefiniowanej listy/grupy i albo spacją za nim albo nową linią albo EOF.

Pozostało 580 znaków

2010-12-10 11:21
Moderator

Rejestracja: 9 lat temu

Ostatnio: 13 godzin temu

0

Ok, rozumiem mój błąd. Teraz będzie konkretniej:

wejście ==> wyjście

Ala ma dodatek d kota ==> dodatek d
Ala ma dodatek X kota ==> dodatek X
Ala ma (dodatek d) kota ==> dodatek d
Ala ma dodatek d. i kota ==> dodatek d
Ala ma dodatek d, i kota ==> dodatek d
Ala ma dodatek a-b do kota ==> dodatek a
Ala ma dodatek do kota ==> [brak dopasowania]
Ala ma dodatek aaa-bbbb do kota ==> [brak dopasowania]
Ala ma dodatek. ==> [brak dopasowania]

Mój tok myślowy po prostu utknął, nie widzę jak dopasować znak lub nie na podstawie tego co jest za nim... poza oczywiście znacznikami $ lub >, ale to nie daje mi tej funkcjonalności, którą bym chciała.
RegExpy dotNetowe.

edytowany 1x, ostatnio: aurel, 2010-12-10 11:22

Pozostało 580 znaków

Bury pajac
2010-12-10 11:32
Bury pajac
0

Rozwiązanie: "(dodatek [a-zA-Z])[^a-zA-Z0-9]"
Testowane na stronie: http://regexp.pl/
Dla danych wejsciowych:

Ala ma dodatek d kota
Ala ma dodatek X kota
Ala ma (dodatek d) kota
Ala ma dodatek d. i kota
Ala ma dodatek d, i kota
Ala ma dodatek a-b do kota
Ala ma dodatek do kota
Ala ma dodatek aaa-bbbb do kota
Ala ma dodatek.

Jako nagrodę wybieram Twoją fotkę, z dzisiejszą krakowską gazetą, aby nie było że mi wciskasz szajs.

Pozostało 580 znaków

2010-12-10 12:21
Moderator

Rejestracja: 9 lat temu

Ostatnio: 13 godzin temu

0

Widzę, że będzie z tym ciężko jednak :/ niestety Bury pajacu, twoja odpowiedź mnie nie satysfakcjonuje, ponieważ to moje zapytanie to jedynie część większego zapytania regularnego (które rozrosło się już z resztą niemiłosiernie...). Postaram się przybliżyć:

Na przykładzie: dodatek a-b
dodatek - to tak naprawdę wyrażenie regularne na wiele różnych słów, które mogą tu wystąpić. Są podzielone na dwie grupy, zależnie od tego do której grupy wyraz należy w dalszej części będzie wymagany nawias lub nie. Nazwijmy je REGEXP_WYRAZ1 i REGEXP_WYRAZ2
a, b - to kolejne wyrażenie regularne. A i B mogą być: pojedynczą literą, liczbą rzymską, liczbą arabską, liczbą arabską, po której nastąpi dowolna liczba liter. Nazwijmy go REGEXP_NR.
REGEXP_NR jest NIESTETY wykorzystywany w wielu miejscach w programie, i nie moge swobodnie wstawić tam np. niezamkniętego nawiasu. To wyrażenie musi być atomowe. Jest zbudowane z dwóch jeszcze bardziej atomowych części, REGEXP_NR_NORMALNY i REGEXP_NR_RZYMSKI gdzie jedno jest dla rzymskich a drugie dla kombinacji liter i cyfr. REGEXP_NR_NORMALNY jest miejscem problemu - to tu jest zapis, który dotyczy liter i pozwala zaznaczyć pojedynczą literę bez warunku co dalej. To tu potrzebna jest zmiana.

Ogólna koncepcja w tej chwili to (będę łączyć stringi plusem):

"^( ?" + "(" + REGEXP_WYRAZ1 + "\.?" + " " + REGEXP_DOZWOLONE_ZNAKI_POMIEDZY1  + "|" + REGEXP_WYRAZ2 + "\.?" + " " + REGEXP_DOZWOLONE_ZNAKI_POMIEDZY2 + ")" + " " + REGEXP_NR + ")+$"

gdzie REGEXP_NR wygląda mniej więcej tak:

"((" +REGEXP_NR_RZYMSKI + "(" + DajMyslnikRegexp + REGEXP_NR_RZYMSKI + ")" + ")" 
+ "|(" + REGEXP_NR_RZYMSKI + "(" + DajMyslnikRegexp + REGEXP_NR_NORMALNY + ")?" + ")" 
+ "|(" & REGEXP_NR_NORMALNY + "(" + DajMyslnikRegexp + REGEXP_NR_NORMALNY + ")?" + "))"

co oznacza, że moga wystąpić kombinacje takie jak np. 10-15a, III-232, IV-XXXII.

Fiu. Mam nadzieję, że się nie walnęłam.
Obecnie to wygląda tak: http://wklej.org/id/435252/ Starałam się choć delikatnie enterami oddzielić bloki od siebie, ale sami widzicie, że wygląda to jak sajgon i tyle. Działa jednak bardzo dobrze, dla wszystkich "ciekawych" przypadków, poza tym, w którym nie ma numeru :/ Wtedy spoko, jeśli nie dopasuje - jak mówiłam, jest oddzielny mechanizm, który tu przypilnuje, żeby wychwycić co trzeba (czyli pojedynczy wyraz). Problem jest w tym, że mi zaciąga literę z następnego wyrazu.
I mam do wyboru - przeskoczyć jakoś ten jeden drobny błąd, albo wywalić cały mechanizm i napisać od nowa... Tak blisko ukończenia chciałabym tego uniknąć...

Edit (sory, za wyświetalnie go pokawałku - niechcący wysłałam w trakcie edycji):
A no i może jeszcze przykłady - tym razem dokładniejsze i bardziej zróżnicowane, żeby wiadomo było o co chodzi:

Ala art. 15 k.c. ==> art. 15
Ala art. III-233 k.c. ==> art. III-233
Ala art. V k.c. ==> art. V
Ala art. 15a-17abc k.c. ==> art. 15a-17abc
Ala art. A k.c. ==> art. A
Ala art. A-B k.c. ==> art. A-B
Ala art. ABC k.c. ==> [brak dopasowania]
Ala art. 5, 6, 7 ==> art. 5
Ala art. 5. ==> art. 5
Ala (art. 15) ==> art. 15

Ok, na razie chyba starczy.

edytowany 5x, ostatnio: aurel, 2010-12-10 13:48

Pozostało 580 znaków

Bury pajac
2010-12-10 13:00
Bury pajac
0

Dotychczasowy solution: "(art. (([A-Za-z])|([0-9]+([a-zA-Z]+)?)|(M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})))(-([0-9]*)([a-zA-Z]+)?)?)[^a-zA-Z]"

Testowane tam gdzie przedtem.

Czy może masz jeszcze jakieś kontrprzykłady?
Jak nie to: fotka.

Pozostało 580 znaków

2010-12-10 13:51
Moderator

Rejestracja: 9 lat temu

Ostatnio: 13 godzin temu

0

Niestety, nie bangla :(
nie działa dla:
art. 5,
art. 15-17,

Chwyta przecinek, choć nie powinien. Chwyta spacje, jeśli są na końcu, oraz znaki nowej linii. Jednocześnie jeśli dodam te znaki do [a-zA-Z] to też nie jest dostatecznie dobre, bo np. spacji dodać nie mogę, bo przestanie chwytać art. 5 ust. 3 (całe wyrażenie jest objęte dodatkowo przez "( ?" i ")+$")

Poza tym takie coś nie dopasowuje zwykłego: "art. V". Dopasuje za to "art. V ", ale przecież nie ma wyrażenie obejmować tej spacji na końcu... Czyżby w tym podejściu mimo wszystko było wymagane, by jakiś znak wystąpił po dopasowaniu?

edytowany 1x, ostatnio: aurel, 2010-12-10 13:55

Pozostało 580 znaków

Bury pajac
2010-12-10 14:01
Bury pajac
0
aurel napisał(a)

Niestety, nie bangla :(
nie działa dla:
art. 5,
art. 15-17,
Chwyta przecinek, choć nie powinien. Chwyta spacje, jeśli są na końcu, oraz znaki nowej linii.

Bangla, tylko źle to odczytujesz: http://regexp.pl/main/show/27112 Ciąg przy cyfrze to cały text, który pasuje, natomiast to o co Ci chodzi to pierwsza kropka po liczbach arabskich. W matcherach C# to jest przedstawiane bodajże jako match.Groups[1].Value ale nie mam pewności.

Pozostało 580 znaków

2010-12-10 14:17
Moderator

Rejestracja: 9 lat temu

Ostatnio: 13 godzin temu

0

Mimo to niedopasowuje najprostszego przykładu: http://regexp.pl/main/show/27112
Poza tym obawiam się, że nawet jeśli Groups[1] zwróci dobrą wartość dla tego fragmentu - czy wciąż dobrze się zachowa dla CAŁEGO wyrażenia? Gdybam, trzeba by potestować, może faktycznie w tę stronę trzeba by się kierować.

Pozostało 580 znaków

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