[Wyrażenie regularne] Koniec wyrazu

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ść?

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ą.

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).

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.

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.

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.

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.

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.

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?

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.

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ć.

0
aurel napisał(a)

Mimo to niedopasowuje najprostszego przykładu: http://regexp.pl/main/show/27112

No przecież:

  1. art. 5,
    * art. 5
    * 5
    * 5
    2. art. 15-17,
    * art. 15-17
    * 15
    * 15
    * -17
    * 17

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ć.

Jeśli nie Groups[1] to z jakimś innym indexem, wszystko co masz pomiędzy nawiasami "( * )" to jest grupa. Potestuj.

Mimo to bład i tak jest dla "art. 5 ust. 3" http://regexp.pl/main/show/27117
Natomiast dla "art. 5 ust. 3 " jest ok http://regexp.pl/main/show/27115

Jeśli mam to poprawić, potrzebuję motywacji - fota.

0
Bury pajac napisał(a)

No przecież:

  1. art. 5,
    * art. 5
    * 5
    * 5
    2. art. 15-17,
    * art. 15-17
    * 15
    * 15
    * -17
    * 17

Przecież ja nie mogę założyć, że w tekście po art. 5 na pewno będzie jeszcze jakiś znak... a dla sytuacji gdy nie ma - powyższe zwróci false.
Rozumiem, że dla "art. 5," zwróci "art. 5", ale dla "art. 5" zwróci nic.

Jak dam fotkę, to jaka będzie motywacja? Cel osiągnięty, wszyscy się z topicu zmyją...

0
aurel napisał(a)

Jak dam fotkę, to jaka będzie motywacja? Cel osiągnięty, wszyscy się z topicu zmyją...

Poprawione http://regexp.pl/main/show/27123
Teraz fotka.

0

Bury pajacu -> wielkie dzięki za nieocenioną pomoc (jakże bezinteresowną :P)
Jednakże, muszę ten problem pociągnąć dalej, stąd odświeżenie tematu. Oto przypadek testowy: http://regexp.pl/main/show/27908
Jak widać jest mi potrzebne, by zaznaczył cały ciąg:

art. 15 ust. 13

Przecinki, kropki ciąg ten przerywają. Niestety, korzystając wyrażenia, które Bury pajac przygotował, mogę dopasować tylko pojedyncze jednostki. Chodzi o to, że w groups (czy w VBA submatches) podpozycje są bez powtórzeń... Czyli wracam do punktu wyjścia, bo w głównym dopasowaniu zachacza mi ten cholerny przecinek... Już nie wspominając o komplikacjach wynikających z podejmowania decyzji, czy teraz zastosować submatches czy też nie :(

Dla tych co potrzebują motywacji - fotka: http://img43.imageshack.us/img43/9025/fotkabr.jpg :>

0

Znaczy chcesz aby wynik był taki: http://regexp.pl/main/show/27917
czy taki http://regexp.pl/main/show/27918
To wersje trialowe, fulla nie dostaniesz za takie coś:

aurel napisał(a)

Dla tych co potrzebują motywacji - fotka: http://img43.imageshack.us/img43/9025/fotkabr.jpg :>

Lepiej mi się myśli jak nadmiar krwi odpłynie mi z mózgu w <inne miejsce="miejsce">.

Tak btw. nie możesz zastosować też regexpów do zwracanych wyników, aby rozpoznać czy rozpoznano kilkukrotne trafienie czy pojedyńcze?

0

z tego: http://regexp.pl/main/show/27917

1. art. 15 ust. 3
* ust. 3
* ust
* 3
* 3
2. art. 15,
** * art. 15**
* art
* 15
* 15
* ,
3. ust. 3
** * ust. 3**
* ust
* 3
* 3
4. art. 15)
** * art. 15**
* art
* 15
* 15
* )

Tak btw. nie możesz zastosować też regexpów do zwracanych wyników, aby rozpoznać czy rozpoznano kilkukrotne trafienie czy pojedyńcze?

Bardzo dobry pomysł... Dzięki znów :)
Już za długo po prostu siedzę na tym jednym projektem, mózg mi utyka w kierunkach myślenia :/

btw. nie wiem co się w fotce nie podoba :P

0
aurel napisał(a)

Już za długo po prostu siedzę na tym jednym projektem, mózg mi utyka w kierunkach myślenia :/

Jak wstawisz swoją prawdziwą fotkę, to będę mógł rzucić zaklęcie na "drożność kierunków myślenia" i skończą się Twoje problemy. Uda się tylko na prawdziwej fotce.

btw. nie wiem co się w fotce nie podoba :P

To lesba, bo używa produktów ejpla.

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