it-swarm.com.de

Regex für String, der nicht mit dem angegebenen Suffix endet

Ich konnte keine passende Regex finden, die mit irgendeiner Zeichenfolge nicht übereinstimmt und mit einer Bedingung endet. Zum Beispiel möchte ich nichts übereinstimmen, das mit einer a endet.

Das stimmt überein

b
ab
1

Das passt nicht zu

a
ba

Ich weiß, dass der Regex mit $ endet, um das Ende zu kennzeichnen, obwohl ich nicht weiß, was ihm vorangehen soll.

Edit: Die ursprüngliche Frage scheint kein echtes Beispiel für meinen Fall zu sein. Also: wie soll man mit mehr als einem Charakter umgehen? Sagen Sie etwas, das nicht mit ab endet.

Ich konnte das Problem mithilfe von diesem Thread beheben:

.*(?:(?!ab).).$

Der Nachteil dabei ist, dass es nicht mit einer Zeichenfolge eines Zeichens übereinstimmt.

129
Menno

Sie geben uns nicht die Sprache, aber wenn Ihr Regex-Geschmack unterstützt schauen Sie hinter die Behauptung , dann brauchen Sie Folgendes:

.*(?<!a)$

(?<!a) ist eine negierte Lookbehind-Assertion, die sicherstellt, dass vor dem Ende des Strings (oder der Zeile mit dem Modifizierer m) das Zeichen "a" nicht angezeigt wird.

Sehen Sie es hier auf Regexr

Sie können dies auch leicht mit anderen Zeichen erweitern, da diese Prüfung für die Zeichenfolge keine Zeichenklasse ist.

.*(?<!ab)$

Dies würde zu allem passen, was nicht mit "ab" endet, siehe Regexr

169
stema

Verwenden Sie das Symbol not (^):

.*[^a]$

Wenn Sie das ^-Symbol an den Anfang der Klammern setzen, bedeutet dies "alles außer den Dingen in den Klammern". $ ist einfach ein Anker zum Ende.

Für mehrere Zeichen füge einfach alle in ihren eigenen Zeichensatz ein:

.*[^a][^b]$
52
Doorknob

Um nach Dateien zu suchen, die nicht mit ".tmp" enden, verwenden wir den folgenden regulären Ausdruck: 

^(?!.*[.]tmp$).*$

Getestet mit dem Regex Tester ergibt folgendes Ergebnis: 

 enter image description here

30
FiveO
.*[^a]$

der Regex oben stimmt mit Strings überein, die nicht mit a enden.

7
Kent

Versuche dies

/.*[^a]$/

Der [] bezeichnet eine Zeichenklasse und der ^ invertiert die Zeichenklasse so, dass sie mit allem außer einer a übereinstimmt. 

3
JesperE

Wenn Sie grep oder sed verwenden, ist die Syntax etwas anders. Beachten Sie, dass die sequentielle [^a][^b]-Methode hier nicht funktioniert:

[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n'
jd8a
8$fb
q(c
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a]$"
8$fb
q(c
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b]$"
jd8a
q(c
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^c]$"
jd8a
8$fb
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^b]$"
jd8a
q(c
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^c]$"
jd8a
8$fb
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^b]$"
q(c
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^c]$"
8$fb
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c]$"
jd8a
[email protected]:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c^a]$"

FWIW, ich finde die gleichen Ergebnisse in Regex101 , was meiner Meinung nach JavaScript-Syntax ist.

Schlecht: https://regex101.com/r/MJGAmX/2
Gut: https://regex101.com/r/LzrIBu/2

0
abalter

Die Frage ist alt, aber ich konnte keine bessere Lösung finden, die ich hier poste. Finden Sie alle USB-Laufwerke, ohne die Partitionen aufzulisten und entfernen Sie so den "Part [0-9]" aus den Ergebnissen. Am Ende habe ich zwei grep gemacht, der letzte negiert das Ergebnis:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

Das ergibt sich auf meinem System:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Wenn ich nur die Partitionen haben möchte, könnte ich:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

Wo bekomme ich:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

Und wenn ich es tue:

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Ich bekomme:

/dev/sdb
0
tombert

Die akzeptierte Antwort ist in Ordnung, wenn Sie Lookarounds verwenden können. Es gibt jedoch auch einen anderen Ansatz, um dieses Problem zu lösen.

Betrachten wir den weithin vorgeschlagenen Regex für diese Frage:

.*[^a]$

Wir werden feststellen, dass es fast funktioniert. Eine leere Zeichenfolge wird nicht akzeptiert, was möglicherweise etwas uninteressant ist. Dies ist jedoch ein geringfügiges Problem, wenn Sie nur mit einem Zeichen arbeiten. Wenn wir jedoch die gesamte Zeichenfolge ausschließen möchten, z. "abc", dann:

.*[^a][^b][^c]$

nicht tun Es wird zum Beispiel keine AC akzeptiert.

Es gibt jedoch eine einfache Lösung für dieses Problem. Wir können einfach sagen:

.{,2}$|.*[^a][^b][^c]$

oder allgemeinere Version:

.{,n-1}$|.*[^firstchar][^secondchar]$ Dabei ist n die Länge der Zeichenfolge, die verboten werden soll (für abc ist es 3), und firstchar, secondchar, ... sind die ersten, zweiten ... nten Zeichen Ihrer Zeichenfolge (für abc wäre dies a) b, dann c).

Dies beruht auf einer einfachen Beobachtung, dass eine Zeichenfolge, die kürzer als der Text ist, den wir nicht verbieten, diesen Text nicht per Definition enthalten kann. Also können wir entweder alles akzeptieren, was kürzer ist ("ab" ist nicht "abc") oder etwas, das wir lange genug akzeptieren können, aber ohne das Ende.

Hier ein Beispiel für find, bei dem alle Dateien gelöscht werden, die nicht jpg sind:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete

0
MatthewRock

Alles, was zu einem Ergebnis passt, das mit einem --- .*a$ endet. Wenn Sie den Regex abgleichen, negieren Sie die Bedingung Alternativ können Sie auch .*[^a]$ tun, wobei [^a] alles bedeutet, das not a ist.

0
Bill