Jak dopasować dowolny inny znak niż spacja oprócz określonego?

111

W Perlu \Sdopasowuje każdy znak niebędący białą spacją.

Jak mogę dopasować dowolny znak niebędący białymi znakami z wyjątkiem odwrotnego ukośnika \?

Lazer
źródło

Odpowiedzi:

154

Możesz użyć klasy postaci :

/[^\s\\]/

dopasowuje wszystko, co nie jest białym znakiem ani znakiem \. Oto kolejny przykład:

[abc]oznacza „meczu a, balbo c”; [^abc]oznacza „dowolny znak z wyjątkiem a, balbo c”.

Tim Pietzcker
źródło
Kiedy jest ^interpretowane jako negacja, a kiedy jako początek linii? W związku z tym, dlaczego nie pasuje do linii zaczynającej się od liczby białych spacji$0~/\s*^\s/
Alexander Cska
1
Poza klasą znaków jest to „początek łańcucha” (lub linii, w zależności od bieżącego trybu dopasowania). Wewnątrz klasy znaków i tylko wtedy, gdy jest to pierwszy znak po nawiasie otwierającym, neguje zawartość klasy znaków.
Tim Pietzcker
Czy następująca linia dopasowania, która zaczyna się od liczby białych spacji, $0~/\s*^\s/po których następuje dowolny znak, który nie jest białymi spacjami
Alexander Cska
1
Prawdopodobnie powinno to być /^\s+/- początek wiersza, po którym następuje jeden lub więcej białych znaków.
Tim Pietzcker
1
@AlexanderCska, rozgryzłeś to? Powyższa odpowiedź zwróci tylko pierwsze dopasowanie ciągu. Jeśli chcesz, aby zwracane były wszystkie dopasowania, dodaj gmodyfikator. /[^\s\\]/g
Ben Carp
14

Możesz użyć lookahead:

/(?=\S)[^\\]/
Denis de Bernardy
źródło
2
Spogląda w przyszłość, jeśli nie jest to przestrzeń. A następnie klasa ujemna akceptuje wszystko (co nie jest spacją) z wyjątkiem znaków z Twojej klasy.
Denis de Bernardy,
Podoba mi się to rozwiązanie. /(?=\S)\W/
Przydaje się
Miałem sytuację, w której musiałem dopasować dowolny znak niebędący białymi znakami, a także nie cudzysłowy. Musiał też pozwolić na SPACES. Np THIS IS A TEST, AND AGAIN. : . Poniższe działały dobrze dla mnie (?=\S)[^"]*.
Arvo Bowen
zaakceptowana odpowiedź nie zadziałała dla mnie, ale tak się stało. użyłem tego w wysublimowanym wyszukiwaniu wyrażeń regularnych tekstu
Christian Noel
5

To zadziałało dla mnie przy użyciu sed [ Edytuj: komentarz poniżej wskazuje, że sed nie obsługuje \ s]

[^ ]

podczas

[^\s] 

nie

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

echo "ghai ghai" | sed "s/[^ g]//g"
g g
burza_m2138
źródło
3
\sdopasowuje więcej niż tylko znak spacji. Obejmuje TAB, wysuw powrót karetki i inne (jak wiele innych w zależności od smaku regex). To wynalazek Perla, pierwotnie skrót klasy znaków POSIX [:space:]i nie jest obsługiwany w sed. Twoje pierwsze wyrażenie regularne powyżej powinno mieć postać s/[^[:space:]g]//g.
Alan Moore,
Tak @AlanMoore działa: Zyski echo "ghai ghai" | sed "s/[^[:space:]g]//g" :g g
storm_m2138
1

W moim systemie: CentOS 5

Mogę używać \spoza kolekcjami, ale muszę używać [:space:]wewnątrz kolekcji. W rzeczywistości mogę używać [:space:]tylko wewnątrz kolekcji. Więc aby dopasować pojedynczą spację używając tego, muszę użyć [[:space:]] Co jest naprawdę dziwne.

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

Result: a b cX
  • pierwsza spacja, do której pasuję \s
  • drugą spację dopasowuję naprzemiennie [[:space:]]
  • dopasowanie XI z „all but no space” [^[:space:]]

Te dwa nie będą działać:

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

a[^\s]b      instead use a[^[:space:]]b
Torge
źródło
1
Od seda 4.4 nadal prawdą jest, że musisz używać ([^[:space:]])zamiast ([^\s]). Jestem na openSUSE Tumbleweed 2018 04 03.
user2394284