Regex Regel

Hallo zusammen,

ich benötige einen regulären Ausdruck, welcher mir folgende Regel realisiert.
In einem beliebigen Pattern dürfen Strings vorkommen die folgendem Muster entsprechen:
&#, also beispielsweise &ABC123# ( ist hierbei entweder eine Zahl oder ein buchstabe)
Ein derartiges Pattern könnte also folgendermaßen aussehen:
Hierirgendwo&ABC#istderStringversteckt.
Es könnten allerdings auch mehrere derartige Strings vorkommen, z.B.
Hiersind&ABC#sogarzwei&XYZ#versteckt.

Es soll nun geprüft werden, dass wenn ein oder mehrere Strings vorkommen, welche mit & anfangen, dass diese auch mit # abgeschlossen sind.

Wie würde hier eine entsprechende Regex Prüfung aussehen? Danke für ein paar Antworten…

Das Programm soll also darauf hinweisen, wenn ein Pattern folgendermaßen vorkommt:
DerStringindiesemPattern&ABCistnichtvollständigweileinHashfehlt

Es muss lediglich geprüft werden,ob das Hash fehlt bzw. vielleicht sogar zuviele Hashs angehängt worden sind.
Daswäre&ABC#korrekt

Daswäre&ABC##nichtkorrekt

Daswäre&ABCauch&XYZ#nichtkorrekt

Probier es mal mit:

^[^&#]*(&[^&#]*#[^&#]*)*[^&#]*$

ich kann dir diese Website empfehlen: Javascript Regex Generator
Der ist zwar für Javascrpit gedacht, jedoch kann man das Grundlegende auch für Java verwenden.

Gibt bei google bestimmt auch noch andere.

Danke, dass scheint zu funktionieren!

Ich würde das nicht mit Regex machen sondern die einzelnen Chars im String vergleichen. Ist sicherlich schneller, leichter zu lesen als die lustige Regex von rudolph, und du weist zu welchem & das # fehlt.
Code wäre ungefährt so (ungetestet):

String s = "foo.....bar";
int index = 0;
int lastAmp = -1;
boolean foundAmp = false;
for (char c : s.toCharArray()) {
    if (c == '&') {
        if (foundAmp) {
            System.out.error("Letztes & an Stelle " + lastAmp + " ist nich mit # beendet worden!");
            break;
        } else {
            foundAmp = true;
            lastAmp = index;
        }
    }
    else if (c ==  '#') {
        if (foundAmp) {
            foundAmp = false;
            lastAmp = -1;
        } else {
            System.out.println("# an Stelle " + index + " gefunden ohne vorheriges &");
            break;
        }
    }

    index++;
}
if (foundAmp) {
    System.out.error("Letztes & an Stelle " + lastAmp + " ist nich mit # beendet worden!");
}```
Man könnte natürlich noch foundAmp durch (lastAmp != -1) ersetzen, aber so ist's denk ich klarer.

Ich hab Hoax Ansatz mal in eine Klasse verpackt.

public class BeginAndEndTester {

    public class Result {
        private boolean ok;
        private String errorMesssage;
        public Result(boolean ok, String errorMesssage) {
            super();
            this.ok = ok;
            this.errorMesssage = errorMesssage;
        }
        public boolean isOk() {
            return ok;
        }
        public String getErrorMesssage() {
            return errorMesssage;
        }
    }

    private char begin;

    private char end;

    public BeginAndEndTester(char begin, char end) {
        super();
        this.begin = begin;
        this.end = end;
    }

    public Result check(String text) {
        int index = 0;
        int lastBeginPosition = -1;
        boolean foundBegin = false;
        for (char c : text.toCharArray()) {
            if (c == begin) {
                if (foundBegin) {
                    return new Result(false, "Letztes '" + begin
                            + "' an Stelle " + lastBeginPosition
                            + " ist nicht mit '" + end + "' beendet worden!");
                }
                else {
                    foundBegin = true;
                    lastBeginPosition = index;
                }
            }
            else if (c == end) {
                if (foundBegin) {
                    foundBegin = false;
                    lastBeginPosition = -1;
                }
                else {
                    return new Result(false, "Ein '" + end
                            + "' wurde an  Stelle " + index
                            + " gefunden ohne vorheriges '" + begin + "'!");
                }
            }

            index++;
        }
        if (foundBegin) {
            return new Result(false, "Letztes '" + begin
                    + "' an Stelle " + lastBeginPosition
                    + " ist nicht mit '" + end + "' beendet worden!");
        }
        return new Result(true,  "");
    }

}

Testcode:


import static org.junit.Assert.*;

import org.junit.Test;

import forum.BeginAndEndTester.Result;

public class BeginAndEndTesterTest {

    @Test
    public void create() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        assertNotNull(tester);
    }

    @Test
    public void testOk1() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "abc &def# ghi";
        Result result = tester.check(input);
        assertEquals(true, result.isOk());
        assertEquals("", result.getErrorMesssage());
    }

    @Test
    public void testOk2() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "abc &def# ghi &jhk# lmn";
        Result result = tester.check(input);
        assertEquals(true, result.isOk());
        assertEquals("", result.getErrorMesssage());
    }

    @Test
    public void testOk3() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "abc";
        Result result = tester.check(input);
        assertEquals(true, result.isOk());
        assertEquals("", result.getErrorMesssage());
    }

    @Test
    public void testOk4() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "";
        Result result = tester.check(input);
        assertEquals(true, result.isOk());
        assertEquals("", result.getErrorMesssage());
    }

    @Test
    public void testOk5() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "&#";
        Result result = tester.check(input);
        assertEquals(true, result.isOk());
        assertEquals("", result.getErrorMesssage());
    }

    @Test
    public void testOk6() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#&#";
        Result result = tester.check(input);
        assertEquals(true, result.isOk());
        assertEquals("", result.getErrorMesssage());
    }

    @Test
    public void testFail1() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "&";
        Result result = tester.check(input);
        assertEquals(false, result.isOk());
        assertEquals("Letztes '&' an Stelle 0 ist nicht mit '#' beendet worden!",
                result.getErrorMesssage());
    }

    @Test
    public void testFail2() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "#";
        Result result = tester.check(input);
        assertEquals(false, result.isOk());
        assertEquals("Ein '#' wurde an  Stelle 0 gefunden ohne vorheriges '&'!",
                result.getErrorMesssage());
    }

    @Test
    public void testFail3() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "#&";
        Result result = tester.check(input);
        assertEquals(false, result.isOk());
        assertEquals("Ein '#' wurde an  Stelle 0 gefunden ohne vorheriges '&'!",
                result.getErrorMesssage());
    }

    @Test
    public void testFail4() {
        BeginAndEndTester tester = new BeginAndEndTester('&', '#');
        String input = "abc &de&ghi#f# jhk";
        Result result = tester.check(input);
        assertEquals(false, result.isOk());
        assertEquals("Letztes '&' an Stelle 4 ist nicht mit '#' beendet worden!",
                result.getErrorMesssage());
    }

}

Naja. Wenn man schon wissen will, wo es kracht und daher eine kompliziertere Lösung braucht, als eine kurze Regex, dann kann man gleich einen Parser nehmen. Das ist aber alles wahrscheinlich ein kompletter Overkill. Wenn man die Regex in eine Methode verpackt, deren Name beschreibt, was sie macht, dürfte das doch gar kein Problem sein.

Btw: um solche Tests zu machen, bietet sich TestNG an. Mit dem DataProvider hat man das alles in zwei Methoden - eine für gültige und eine für ungültige Teststrings plus zwei Arrays mit den Strings.