Regular expressions

    Hogy befejezzük ezt a fejezetet, szabályos kifejezéseket fogunk megnézni, amik hozzá lettek adva
JDK 1.4-hez és benne vannak a Standard Unix-ban, olyan programokra gondolva mint Sed &
awk, mely nyelvek kedvelik Pythont és Perlt (néhányan  bizonyítanák, hogy az ő
túlnyomó indokuk a vezetett a Perl's sikeréhez). Technikailag ezek sztringekkel való müveletek(előzőleg deklarált String, Stringbuffer,StringTokenizer osztályok a Javaban),
de ezeket tipikusan I/O kapcsolatoknál használjuk, tehát nem túlzott őket ebben a részben tárgyalni.


    A reguláris kifejezések erőteljes és rugalmas szövegfeldolgozás-eszközök. Megengedi neked, hogy részletezd a szöveg mintáit, egy beviteli sztringbe.
Amint felfedezed ezeket a mintákat, rögötn reagálni tudsz rájuk, úgy ahogy akarsz.
Bár a szabályos kifejezések szintaxisai megfélemlítőek lehetnek, ennek ellenére egy dinamikus nyelvet nyújtanak, melynek alkalmazásával megoldhatunk mindeféle sztring feldolgozást, összeillesztést és kiválasztást,szerkesztést és ellenőrzési problémák megoldásához egy teljesen egyszerű út.


Szabályos kifejezések létrehozása

   
Egy lehetséges változat, hogy elkezdesz egy hasznos alhalmazzal reguláris kifejezéseket megtanulni. A komplett szerkezetlista a szabályos kifejezések kreálásához megtalálható a JavaDocs-on belül a Pattern oszályban java.util.regexet csomagolt fájlban.


Karakterek
B B specifikus karakter
\xhh karakter hex-el vagy oxhh-val
\uhhh Unicode karakterek ábrázolása hex-val
\t Tab
\n újsor
\r kurzor visszaugrás
\f formát betölt
\e Kilépés


A reguláris kifejezések előnye ott mutatkozik meg, mikor definiálni akarunk egy karakterosztályt.Itt van néhány tipikus példa, hogy hogyan hozzunk létre karakterosztályokat és néhány előredefiniált osztályt.

Karakter osztályok
. Reprezenál minden karaktert
[abc] Bármely karakter, a,b,c
[^abc] Bármely karakter közül az egyik
[a-zA-Z] Bármely karakter  "a"-tól "z"-ig vagy "A"-tól "Z"-ig
[abc[hij]] Bármely karakter a,b,c közül vagy h,i,j közül
[a-z&&[hij]] Valamelyik karakter "a"-tól "z"ig és  h,i vagy j
\s fehérkarakter (szóköz, tab, újsor...)
\S Nem fehérkarakter
\d Numerikus karakterek 0-9-ig
\D Nem numerikus karakterek
\w betűk+számok
\W nem betűkarakterek és nem számok


Ha rendelkezel bármilyen másik nyelvekben lévő rendszeres kifejezésekkel kapcsolatos tapasztalattal,
azonnal észre fogsz venni egy különbséget, mégpedig a backslasheket kezelésével kapcsolatban.
Másik nyelvekben, "\\" azt jelenti, hogy "be akarok illeszteni egy sima régi (szó szerinti)
backslash a reguláris kifejezésben. Nem adja azt bármennyire is azt jelentené." A Java-ban a \\ azt jelenti, hogy "Beillesztek egy reguláris kifejezés backslasht, tehát a következő karakternek van különleges jelentése." Például ha azt akarod, hogy 1 vagy több szókaraktert jelentes a reguláris kifejezés sztringed, akkor \\w+ használj. Ha viszon backslasht akarsz beilleszteni, akkor használd \\\ a karatersorozatot.
Azonban, ha ujsort bagy tabulátort szeretnél beszúrni, használd a "\n\t" karaktersorozatot.

Amit itt mutatunk az csak egy mintavétel;A java.util.regex.Pattern JDK-ra van szükséged, ahol a doumentáció könyvjelzővel megjelölt, vagy indítsd el a menüt, ahonnan könnyen hozzá tudsz férni a lehetséges reguláris egész minta kifejezéshez.


Logikai operátorok
XY X-et követi Y-on
X|Y X vagy Y
(X) Ez egy lefogó csoport. Később tudsz rá hivatkozni a \i-vel


Boundary Matchers
^ A sor kezdete
$ A sor vége
\b szó megkötés
\B Nincs szó megkötés
\G Vége az előző párosításnak

Ahogy azt a  példa is mutatja, a következők mindegyike érvényes reguláris kifejezések képviselre,
és minden sikeresen össze fogja illeszteni a karaktersorozatot "Rudolph":

    Rudolph
    [rR]udolph
    [rR][aeiou][a-z]ol.*
    R.*


Quantifiers

Egy Quantifier leírja azt az utat, amit egy minta elnyel beviteliszövegként:
   
        Greedy (kapzsi): A kvantorok greedy-k hacsak nem változtatjuk meg. A greedy kifejezések sok lehetséges utat találnak a megoldáshoz. A problémák egy tipikus oka felteszi, hogy a mintád csak össze fogja illeszteni a karakterekből álló első lehetséges csoportot, mikor ez
ténylegesen greedy és állandóan megy.

        Reluctant (vonakodó): kérdőjellel van specifikálva.megegyezezik azzal a minimumszámú karakterre amelyik kielégíti a mintát.Nevezett még lusta minimum egyező nem kapzsi.

        Possessive(birtokos)
Csak javaban érhető el jelenleg , más nyelvben nem.ráadásul ez fejlettebb így valószínűleg nem fogod használni rögtön.Ahogy egy reguláris kifejezést alaklmaznak egy sztringre ez túl sok állapotot hoz létre, tehát ez visszaléphet ha az egyezés nem jö9n létre.A birtokos kvantorok nem tartják azokat a közbenső állapotokat, amelyek a visszalépést akadályzonák meg.arra használhatók, hogy megakadályozza a reguláris kifejezés megszaladását és hatékonyabb végrehatást tesz lehetővé.

nagyon körültekintőnek kell lenned, hogy "x" kifejezésnek gyakran zárójelekben kell megadni az utat, amit szertnél.
pédául:
    abc+

lehet hogy úgy látszik, hogy egyezik a sorozat "abc" egyszer vagy többször és ha ezt mint input szöveget alkalmazod "abcabcabc" három egyezést fogsz kapni.
minazonáltal a kifejezés ténylegesen egyezést mutat az "ab" -vel és az utánna követkeő egy vagy több előfordulásával "c"-nek. Ahozz hogy az egész "abc" szöveget egyeztesd egyszer vagy többször a következőt kell irnod:

(abc)+

könnyen becsaphat ha reguláris kifejezést használsz, ez egy új nyelv a java-n.

CharSequence

a JDK 1.4 egy új interfészt definiál amit Charsequence-nek hivnak, amely megalapít egy karaktersorozat definíciót, amely a string és a stringbuffer osztályokból van szármoztatva.


interface CharSequence {
charAt(int i);
length();
subSequence(int start, int end);
toString();
}

sztring, sztringbuffer és charbuffer osztályokat módosították, hogy megvalósitsák az új char Charsequence interfészt.sok reguláris kifejezésnek van charCharsequence argumentuma.

Pattern and Matcher

Mint az első példaként a következő osztály használható mint teszt reguáris kifejezés az input sztring ellen.az első argumentuma az input sztringnek az egyező követve az egy vagy több reguláris kifejezés álltal, amely az inputra vonatkoztatott.Unix Linux alatt  areguláris kifejezéseknek idézve kell lenni a parancssoron. Ez a program hasznos lehet abban h tesztelt a reguláris kifejezéseket, amint megalkotod őket hogy megnézd hogy nyújtják e az elvárt összeillő viselkedést.

//: c12:TestRegularExpression.java
// Allows you to easly try out regular expressions.
// {Args: abcabcabcdefabc "abc+" "(abc)+" "(abc){2,}" }
import java.util.regex.*;
public class TestRegularExpression {
public static void main(String[] args) {
if(args.length < 2) {
System.out.println("Usage:\n" +
"java TestRegularExpression " +
"characterSequence regularExpression+");
System.exit(0);
}
System.out.println("Input: \"" + args[0] + "\"");
for(int i = 1; i < args.length; i++) {
System.out.println(
"Regular expression: \"" + args[i] + "\"");
Pattern p = Pattern.compile(args[i]);
Matcher m = p.matcher(args[0]);
while(m.find()) {
System.out.println("Match \"" + m.group() +
"\" at positions " +
m.start() + "-" + (m.end() - 1));
}
}
}
} ///:~

Reguláris kifejezések vannak implementálva a java-ban a pattern és matcher osztályokon keresztül a java.util.regex csomagban.A pattern objektum képviseli egy regulásris kifejezés összeállitott verzíóját. A statikus compile() módszer összeálít egy reguláris kifejezés sztringet a pattern objektumba.Mint korábban láttuk használhatod a matcher() módszert és az input sztring létrehoz egy matcher objektumot a lefordított pattern objektumból. A patternek szintén van egy
static boolean matches(String regex, CharSequence input)
hogy gyorsan biztosítjuk ha regex-et találnánk az inputban és a split() metódus ami tömböt hoz létre a sztringől megszakad a regex egyezésénél.
A matcher objektum generálódik a pattern.matcher() meghívásával a bemenő sztringel mint argumentum.A matcher objektumot ekkor arra használják hogy elérje azokat baz eredményeket használva a módszereket, hogy a sikert vagy kudarcot értékeljen ki különböző tipusú egyezésekkel.

boolean matches()
boolean lookingAt()
boolean find()
boolean find(int start)

A matches() módszer sikeres ha a minta egyezik az egész input sztringel, amíg a lookingat() sikeres ha az input sztring  az elejétől egyezik a mintával.

find()

A matcher.find() hasznos lehet ha többszörös minta egyezést kell keresni a charsequence-ben.például

//: c12:FindDemo.java
import java.util.regex.*;
import com.bruceeckel.simpletest.*;
import java.util.*;
public class FindDemo {
private static Test monitor = new Test();
public static void main(String[] args) {
Matcher m = Pattern.compile("\\w+")
.matcher("Evening is full of the linnet's wings");
while(m.find())
System.out.println(m.group());
int i = 0;
while(m.find(i)) {
System.out.print(m.group() + " ");
i++;
}
monitor.expect(new String[] {
"Evening",
"is",
"full",
"of",
"the",
"linnet",
"s",
"wings",
"Evening vening ening ning ing ng g is is s full " +
"full ull ll l of of f the the he e linnet linnet " +
"innet nnet net et t s s wings wings ings ngs gs s "
});
}
} ///:~

A minta "\\w+" mutatja hogy egy vagy több szövegkarakter,tehát ez egyszerűen felvágja az inputot szavakra.A find() olyan mint egy iterátor, végig megy az input szövegen.Minazonáltal a find() második verziójának egy integer argumentumot tudunk adni, ami megadja a karakter pozícióját a kerseés kezdetéhez. Ez a verzió beállitja a keresési pozíciót az argumentum értékeként amint látható az outputból.