Regex szukanie dokładnie jednego wystąpienia podanego znaku

0

Potrzebuje znaleźć w Stringu dokładnie jednego wystąpienia wybranego znaku.
Kombinuje tak

System.out.println(!txt1.matches("[^a]*"));

Jak już pewnie wiecie, nie zawsze daje odpowiedni wynik.

1

Czy próbujesz dostać informację, że jakiś znak występuje w tekście dokładnie jeden raz? Dziwne to Twoje zdanie i wole się upewnić :)
Jeśli tak, to gugle mi podpowiedział dosyć szybko: "^[^a]*a[^a]*$"

2

Polecam sprawdzić swoje wyrażenie w parserze wyrażeń, np. http://regexr.com/. Był ostatnio temat na forum, programowy tester / edytor wyrażeń regularnych.
Jeśli dobrze rozumiem co autor miał na myśli, to nie potrzeba tu wyrażenia. Lepiej zrobić tak: text.contains("a"). Metoda contains odpowiada na pytanie czy podany ciąg znaków znajduje się w tym, którego metoda się tyczy - nieważne w jakim miejscu i nieważne ile razy - ważne, że jest. Opis metody https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#contains(java.lang.CharSequence)
A jeśli już koniecznie chce regex, to tak System.out.println(txt1.matches("[a]"));. Gwiazdka może byłaby spoko, bo każe znaleźć dowolną liczbę podanego znaku. Ale za to [^a] oznacza negację. Czyli wychodzi nam niespodzianka "znajdź dowolną liczbę czegoś, co nie jest znakiem a.

2
baant napisał(a):

Czy próbujesz dostać informację, że jakiś znak występuje w tekście dokładnie jeden raz? Dziwne to Twoje zdanie i wole się upewnić :)
Jeśli tak, to gugle mi podpowiedział dosyć szybko: "^[^a]*a[^a]*$"

To wyrażenie spełni swoje zadanie, ale dopasuje przy okazji cały tekst. To już prościej nie używać regexa wcale:

boolean ok = false;
int a;

for (a = 0; a < text.length(); a++) {
	if (text.charAt(a) == 'a') {
		if (!ok) {
			ok = true;
		} else {
			ok = false;
			break;
		}
	}
}

Po co używać gwiazdek do prostych zadań?

1

Ogólnie, taki pseudo kod

str - dany tekst
key - badany znak

*str. lastIndexOf(key) == str.firstIndexOf(key)
*(first równy last bo wtedy wystąpił tylko jeden raz albo zero razy) i różny od -1 (bo to dało co najmniej jeden znaleziony a -1 zwracane jest kiedy klucz nie występuje w tekście)

Czy Java czy JS to sobie potem dobierasz kosmetykę składni itd.

Nie będę się upierać, że ma być -1 bo może w innym języku albo inna implementacja zwróci jakąś wartość < 0 kiedy nie znaleziono klucza.
Ale na interview ustne one to one takie rozwiązanie jak najbardziej będzie OK.

1

OT, warto używać dostępnych implementacji algorytmów i struktur danych z danego języka.

Np. podobne zadanie typu isUnique(array|string) - czy array|string nie ma powtarzających się wartości.
Zamiast latać O(n^2) pętlami (i się w stresie interview pomylić) jak nam na szybko przyszło do głowy rozwiązanie, można z danych wejściowych stworzyć Set, kiedy rozmiar otrzymanego Set jest równy licznie elementów wejściowych to są one unikatowe/unikalne (kurcze, polski analfabetym wtórny mnie dopadł - unique)

Modelowe O(n^2)

const isUnique = function (arr) {
    let result = true;

    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length; j++) {
            if (i !== j && arr[i] === arr[j]) {
                result = false;
            }
        }
    }

    return result;
};

console.log(isUnique([1, 2, 3]));
console.log(isUnique([1, 1, 3]));
let numbers = [1, 2, 3];
console.log(new Set(numbers).size === numbers.length);

numbers = [1, 1, 3];
console.log(new Set(numbers).size === numbers.length);

Drugie podejście da się już zakodzić na szybko nawet w przeglądarce

A jak miałoby być na życzenie rekrutującego inżyniera wydajnie to prosty cache

const isUnique = function (arr) {
    const cache = {};

    for (let e of arr) {
        if (cache[e]) {
            return false;
        } else {
            cache[e] = true;
        }
    }
    
    return true;
};

Dla Javy zamiast obiektu {} będzie new HashMap(), w JS można tak samo z mapą

const isUnique = function (arr) {
    const cache = new Map();

    for (let e of arr) {
        if (cache.has(e)) {
            return false;
        } else {
            cache.set(e, true);
        }
    }

    return true;
};

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