Wie kann man ein Nicht-Leerzeichen außer einem bestimmten übereinstimmen?

111

In Perl \Sstimmt jedes Nicht-Leerzeichen überein.

Wie kann ich ein Nicht-Leerzeichen außer einem Backslash abgleichen \?

Laser
quelle

Antworten:

154

Sie können eine Zeichenklasse verwenden :

/[^\s\\]/

passt zu allem, was weder ein Leerzeichen noch ein Leerzeichen ist \. Hier ist ein weiteres Beispiel:

[abc]bedeutet „Spiel a, boder c“; [^abc]bedeutet „ mit Ausnahme jedes Zeichen a, boder c“.

Tim Pietzcker
quelle
Wann wird ^als Negation interpretiert und wann als Zeilenanfang? In dieser Hinsicht, warum dies nicht mit einer Linie übereinstimmt, die mit der Anzahl der Leerzeichen $0~/\s*^\s/
beginnt
1
Außerhalb einer Zeichenklasse ist dies "Anfang der Zeichenfolge" (oder Zeile, abhängig vom aktuellen Übereinstimmungsmodus). Innerhalb einer Zeichenklasse und nur wenn es das erste Zeichen nach der öffnenden Klammer ist, wird der Inhalt der Zeichenklasse negiert.
Tim Pietzcker
Wird die folgende Übereinstimmungslinie, die mit einer Anzahl von Leerzeichen beginnt, $0~/\s*^\s/gefolgt von einem Zeichen, das kein Leerzeichen ist
Alexander Cska
1
Das sollte wahrscheinlich sein /^\s+/- Zeilenanfang, gefolgt von einem oder mehreren Leerzeichen.
Tim Pietzcker
1
@AlexanderCska, hast du es herausgefunden? Die obige Antwort gibt nur die erste Übereinstimmung einer Zeichenfolge zurück. Wenn Sie möchten, dass alle Übereinstimmungen zurückgegeben werden, fügen Sie den gModifikator hinzu. /[^\s\\]/g
Ben Carp
14

Sie können einen Lookahead verwenden:

/(?=\S)[^\\]/
Denis de Bernardy
quelle
2
Es schaut nach vorne, wenn es kein Raum ist. Und dann akzeptiert die negative Klasse alles (was kein Leerzeichen ist) außer den Zeichen in Ihrer Klasse.
Denis de Bernardy
Ich mag diese Lösung. Es ist gut für Dinge wie "Gib mir alle Nicht-Wort-Zeichen außer Leerzeichen":/(?=\S)\W/
Jocull
Ich hatte eine Situation, in der ich sowohl Nicht-Leerzeichen als auch Nicht-Anführungszeichen finden musste. Es musste auch SPACES berücksichtigen. Bsp. : THIS IS A TEST, AND AGAIN. Das Folgende hat bei mir gut funktioniert (?=\S)[^"]*.
Arvo Bowen
Die akzeptierte Antwort hat bei mir nicht funktioniert, aber das hat funktioniert. Ich habe dies in der Regex-Suche für erhabenen Text verwendet
Christian Noel
5

Dies funktionierte bei mir mit sed [ Bearbeiten: Kommentar unten weist darauf hin, dass sed \ s nicht unterstützt]

[^ ]

während

[^\s] 

nicht

# Delete everything except space and 'g'
echo "ghai ghai" | sed "s/[^\sg]//g"
gg

echo "ghai ghai" | sed "s/[^ g]//g"
g g
Storm_m2138
quelle
3
\sentspricht mehr als nur dem Leerzeichen. Es enthält TAB, Zeilenvorschubwagenrücklauf und andere (wie viele andere hängen vom Regex-Geschmack ab). Es ist eine Perl-Erfindung, ursprünglich eine Abkürzung für die POSIX-Zeichenklasse [:space:], die in nicht unterstützt wird sed. Ihre erste Regex oben sollte sein s/[^[:space:]g]//g.
Alan Moore
Yup @AlanMoore funktioniert: echo "ghai ghai" | sed "s/[^[:space:]g]//g" Erträge:g g
Storm_m2138
1

Auf meinem System: CentOS 5

Ich kann \saußerhalb von Sammlungen verwenden, muss aber [:space:]innerhalb von Sammlungen verwenden. Tatsächlich kann ich [:space:]nur innerhalb von Sammlungen verwenden. Um ein einzelnes Leerzeichen damit abzugleichen, muss ich das verwenden, [[:space:]] was wirklich seltsam ist.

echo a b cX | sed -r "s/(a\sb[[:space:]]c[^[:space:]])/Result: \1/"

Result: a b cX
  • Erster Platz, mit dem ich übereinstimme \s
  • zweites Leerzeichen, mit dem ich alternativ übereinstimme [[:space:]]
  • das XI-Match mit "alles außer Platz" [^[:space:]]

Diese beiden werden nicht funktionieren:

a[:space:]b  instead use a\sb or a[[:space:]]b

a[^\s]b      instead use a[^[:space:]]b
Torge
quelle
1
Ab sed 4.4 ist es anscheinend immer noch wahr, dass Sie ([^[:space:]])stattdessen verwenden müssen ([^\s]). Ich bin auf openSUSE Tumbleweed 2018 04 03.
user2394284