# Reguläre Ausdrücke formulieren



## ArdianH101 (13. Feb 2016)

Hallo,

ich weiß gar nicht ob das hier überhaupt dazu passt, theoretische Informatik im JAVA Forum, aber wusste gerade nicht wo sonst  

Folgendes:
In der Klausur wird verlangt, dass ich einen regulären Ausdruck von einem Sachverhalt darstelle.
Ich habe erst vor kurzer Zeit begonnen,das nach zu arbeiten, war sehr lange krank in dem Semster :/ 

Aufgabenstellung: 


> Beschreiben Sie die Sprache der ungeraden, ganzen Zahlen ohne führende Nullen mit verpﬂichtendem Vorzeichen durch einen regulären Ausdruck über T = {+,−,0,1,2,3,4,5,6,7,8,9}



Wie kann ich das jetzt formulieren? 
Also rein wörtlich hätte ich das jetzt so gesagt: + muss mit den ungeraden Zahlen von 1,3,5,7 und 9 zusammen hängen. Also 0 zähl ich nicht mit rein. 
Und viel weiter komme ich auch nicht 


Wie schreib ich denn sowas jetzt als regulären Ausdruck? :/

Danke


----------



## kneitzel (13. Feb 2016)

Also verpflichtendes Vorzeichen bedeutet, dass ein + oder ein - kommen muss.
Dann muss eine Ziffer kommen, die nicht 0 sein darf.
Und dann können noch weitere Ziffern kommen in beliebiger Anzahl.

Wie kannst Du diese Teile jeweils darstellen? Dann hast Du die Lösung schon.


----------



## ArdianH101 (13. Feb 2016)

kneitzel hat gesagt.:


> Also verpflichtendes Vorzeichen bedeutet, dass ein + oder ein - kommen muss.
> Dann muss eine Ziffer kommen, die nicht 0 sein darf.
> Und dann können noch weitere Ziffern kommen in beliebiger Anzahl.



ok, also sorry schonmal für meine missversuche aber naja  :
also + oder - als Vorzeichen muss kommen, sprich einfach nur das +|-? 
also:   +|-....usw?

und dann noch die ungeraden Zahlen dranhängen... 
_(+|-).1^+.3^+.5^+.7^+.9^+_
Geht das in die richtige Richtung?


----------



## kneitzel (13. Feb 2016)

Nein, dass ist so leider noch nicht ganz richtig.
Wenn Du für ein Zeichen eine Auswahl angeben willst, dann kannst Du das über [] machen, also z.B. [a-z0-9] würde für ein Zeichen von a-z oder 0-9 stehen.
Wenn Du das wiederholen willst, dann kannst Du die Anzahl in {} dahinter schreiben. Also z.B. [a-z]{3} steht für genau drei Zeichen die jeweils von a-z sein können.
Wenn Du ganze Teilausdrücke per oder Verknüpfen willst, dann ist das | Zeichen richtig.

Und ich hatte vergessen, dass es eine ungerade Zahl sein soll - also die letzte Ziffer muss aus 1,3,5,7 oder 9 bestehen.

Und bei den Tests muss man dann noch darauf achten, dass er ja den ganzen String matchen soll, d.h. Anfang (^) und Ende ($) muss man auch mit matchen.

Half dies etwas? Auf https://regex101.com/ kann man das etwas testen.


----------



## ArdianH101 (14. Feb 2016)

Ok, aber heisst kann ich denn zum Beispiel mit [1-9]{5} schon sagen dass das die ungeraden sind? 
Also scheint mir n bisschen zu ungenau. Zwar hab ich das heißt ja, das genau 5 Zeichen von 1-9. Aber wie kann ich angeben, dass dann die ungeraden gemeint sind? 
*(+|-).[1-9]{5} *wird auch nicht stimmen oder?


----------



## kneitzel (14. Feb 2016)

Also der . steht für ein beliebiges Zeichen. Damit hast Du oben angegeben:
- erst ein + oder -
- dann ein beliebiges Zeichen
- dann 5 Mal eine  Ziffer aus 1-9

(+|-) wird meist als [+-] angegeben. Das ist aus meiner Sicht leichter lesbar.

Woran erkennst Du, ob eine Zahl ungerade ist oder nicht? Wie entscheidest Du das, wenn Du eine Zahl prüfst? 167 ist gerade oder ungerade? 673892 ist gerade oder ungerade? Wie hast du das entschieden? Du wirst die Zahlen ja kaum im Kopf oder mit dem Taschenrechner durch 2 geteilt haben, oder?

Und dann können wir ja mal die Zahlen allgemein beschreiben:
[Vorzeichen][EineZifferOhne0][Beliebige Anzahl Ziffern]
Die kannst Du ja mal als richtigen regulärer Ausdruck beschreiben. Und dann evtl. einfach noch den Sachverhalt vom Anschnitt vorher hinzunehmen. 

Dann hast Du einen ersten Ausdruck und du kannst überlegen, welche Zahlen evtl. noch nicht abgedeckt worden sind. Für diese kannst Du dann eigene reguläre Ausdrücke erstellen um diese dann einfach zu schreiben: (Ausdruck1|Ausdruck2)

Konrad


----------



## ArdianH101 (14. Feb 2016)

kneitzel hat gesagt.:


> Also der . steht für ein beliebiges Zeichen. Damit hast Du oben angegeben:
> - erst ein + oder -
> - dann ein beliebiges Zeichen
> - dann 5 Mal eine  Ziffer aus 1-9
> ...


Also wir haben das so gelernt, dass (x|y) eben x oder y heißt und dass man durch den Punkt, also x.y einfach nur zwei Ziffern aneinander reiht. aber ok egal   (ich würde das nur für dieses Problem gerne in meiner gelernten Variante schreiben, wenn das in Ordnung ist)

Okay also ich erkenne ob eine Zahl gerade ist daran, ob die letzte Zahl gerade oder ungerade ist.

*(+|-).[1-9].[0-9]*.[1|3|5|7|9]^+* 

Dann habe ich laut meinem Verständnis am Anfang ein + oder -, angereiht an eine Ziffer von 1-9, angereiht an eine beliebige Zahl, beliebig oft, angereiht an eine der ungeraden Zahlen von 1-9. und das eben hoch +, weil ungerade Zahlen mit *einer* ungeraden Zahl enden MÜSSEN, aber es könnten auch eine Reihe von ungeraden  Zahlen sein.


----------



## kneitzel (14. Feb 2016)

Also Du solltest da einmal mit den regulären Ausdrücken rumspielen und das alles austesten. Ich weiss nicht, was ihr euch da an Syntax überlegt habt, aber Du kannst das gerne einmal austesten unter https://regex101.com/.

Der . steht halt für ein beliebiges Zeichen.
(+|-) funktioniert nicht, da hier das + schon eine andere Bedeutung hat. Daher wäre sowas wie ((+)|(-)) denkbar oder ([+]|[-]). Aber bei einzelnen Zeichen würde ich einfach immer [...] machen und in den Klammern die erlaubten Zeichen auflisten. 
Besondere Bedeutung hat dann aber auch \ und - und so. 

Nach dem, was Du da bisher erarbeitet hast, wäre der reguläre Ausdruck [+-][1-9][0-9]*[13579]
Damit kann man aber nur ungerade Zahlen ab 2 Ziffern matchen. Und wenn davor oder danach noch andere Zeichen kommen, dann ist das immer noch ok und er matcht auf die Zahl dazwischen. 
Daher kommen da die Zeichen für Anfang und Ende des Textes zur Geltung. ^ steht für den Anfang und $ für das Ende. Und schon matcht der reguläre Ausdruck nicht mehr.

Jetzt fehlt nur noch der Ausdruck für einstellige ungerade Zahlen. Und hier kommt dann dein ( ... | ... ) zum Einsatz.


----------



## ArdianH101 (14. Feb 2016)

Ok, ich werde versuchen mir die üblichere Schreibweise an zu eignen.(Wobei wir das mit dem ^ und dem $ noch nicht gemacht haben, sprich es muss auch ohne gehen)

Hm, ok, dann könnte ich in die Klammer einmal den Ausdruck für eine ungerade einstellige Zahl machen ODER für eine ungerade zwei- oder mehrstellige Zahl?
Sprich:

*([+-][13579]|[+-][1-9][0-9]*[13579]) *?

Noch eine Frage: mit dem [13579] will ich ja sagen, dass 1 oder 3 oder 5, etc. gewählt werden muss.
Wird [13579] jetzt NICHT als eine Zahl angesehen, weil mir vorgegeben ist das 1,3,5,7,9 Teilmengen von T sind?


----------



## kneitzel (14. Feb 2016)

Ja, die Lösung ist schon sehr gut. Ohne die ^ und $ geht es nicht wirklich. Zumindest nicht, wenn Du mit einem Match prüfen willst, ob etwas ok ist oder nicht.
a+123a ist keine gültige Zahl. Wenn Du den regulären Ausdruck anwendest, dann wird er aber matchen, d.h. er findet die +123 und ignoriert einfach das a am Anfang und auch das a am Ende.
(Einfach einmal online test - URL hatte ich ja genannt. Auf der Seite siehst Du dann, dass er den Teil, der matcht, markiert. Wenn Du es online testest, dann findest Du auch noch ein anderes Problem. Die einstellige Zahl hast Du zuerst genannt. Ohne Anfang und Ende vorzugeben kann es nun passieren, dass er genau diese Einstellige Zahl matcht und zufrieden ist. Also beim Beispiel +123 sieht er dann +1 als gefundene Lösung und ignoriert die 2 und 3. Wenn Du die Reihenfolge umdrehst, dann würde es aber wieder klappen.)

In den eckigen Klammern wird eine Menge angegeben und keine Zeichenkette. Also das [abc] steht für a oder b oder c.

Zu Deiner Lösung: Eine Kleinigkeit hast Du noch nicht bedacht: Es soll ja immer ein Vorzeichen geben, also auch bei der einstelligen Zahl. Das müsstest Du noch einbauen.

Aber damit solltest Du eine Lösung haben, die Du in dem regex Tester auch gut vorführen kannst. Und wenn du an den Anfang ein ^ und ans Ende ein $ setzt (weil Du es jetzt auch gehört / gelernt hast, dann hast Du - meiner Meinung nach und auch bezüglich der Tests in dem online Tester - eine sehr gute Lösung.

Ich hoffe, dass alles soweit verständlich war und Du jetzt nicht zu sehr einen Spagat zwischen in der Schule gesagtem und hier gelernten machen musst. (Und in der Hoffnung, dass Dein Lehrer das auch nachvollziehen kann. Nicht dass er auf irgendwas falschem rumhackt - dessen nicht funktionieren Du aber jederzeit in dem online Tester oder mit einer kleinen Test-Applikation prüfen kannst!)


----------



## ArdianH101 (14. Feb 2016)

Ok, ja das mit den Vorzeichen bei der einstelligen ungeraden Zahl habe ich vergessen, habs aber gleich bearbeitet  
Ok, vielen Dank!
Bin echt sehr positiv über das Forum überrascht, hier lernt man rasch dazu!


----------

