Làm cách nào để khớp bất kỳ ký tự không phải khoảng trắng nào ngoại trừ một ký tự cụ thể?


111

Trong Perl \Skhớp với bất kỳ ký tự không có khoảng trắng nào.

Làm cách nào để đối sánh bất kỳ ký tự không có khoảng trắng nào ngoại trừ dấu gạch chéo ngược \?

Câu trả lời:


154

Bạn có thể sử dụng một lớp ký tự :

/[^\s\\]/

khớp với bất kỳ thứ gì không phải là ký tự khoảng trắng cũng không phải là a \. Đây là một ví dụ khác:

[abc]có nghĩa là "khớp a, bhoặc c"; [^abc]có nghĩa là "phù hợp với bất kỳ ký tự trừ a, bhoặc c".


Khi nào được ^hiểu là phủ định và khi nào dòng bắt đầu? Trong khía cạnh đó, tại sao điều này wont phù hợp với một dòng bắt đầu với số lượng chỗ trắng$0~/\s*^\s/
Alexander CSKA

1
Bên ngoài lớp ký tự, đó là "đầu chuỗi" (hoặc dòng, tùy thuộc vào chế độ khớp hiện tại). Bên trong một lớp ký tự và chỉ khi đó là ký tự đầu tiên sau dấu ngoặc mở, nó sẽ phủ định nội dung của lớp ký tự.
Tim Pietzcker

Dòng trận đấu sau đó bắt đầu với một số không gian màu trắng sẽ $0~/\s*^\s/tiếp theo bất kỳ nhân vật đó không phải là một không gian trắng
Alexander CSKA

1
Đó có thể là /^\s+/- bắt đầu dòng, theo sau là một hoặc nhiều ký tự khoảng trắng.
Tim Pietzcker

1
@AlexanderCska, bạn đã tìm ra chưa? Câu trả lời trên sẽ chỉ trả về kết quả phù hợp đầu tiên của một chuỗi. Nếu bạn muốn tất cả các trận đấu được trả về, hãy thêm công cụ gsửa đổi. /[^\s\\]/g
Ben Carp

14

Bạn có thể sử dụng một cái nhìn trước:

/(?=\S)[^\\]/

2
Nó nhìn về phía trước nếu nó không phải là một khoảng trống. Và sau đó lớp phủ định chấp nhận bất kỳ thứ gì (không phải là khoảng trắng) ngoại trừ các ký tự trong lớp của bạn.
Denis de Bernardy

Tôi thích giải pháp này. Đó là tốt cho những thứ như "cho tôi tất cả các ký tự không phải chữ trừ khoảng trắng":/(?=\S)\W/
jocull

Tôi đã gặp một tình huống mà tôi cần phải khớp bất kỳ ký tự không có khoảng trắng nào cũng như không phải dấu ngoặc kép. Nó cũng phải cho phép KHÔNG GIAN. Ví dụ: THIS IS A TEST, AND AGAIN. Điều sau làm việc tốt cho tôi (?=\S)[^"]*.
Arvo Bowen

câu trả lời được chấp nhận không hoạt động với tôi nhưng điều này đã làm. tôi đã sử dụng cái này trong tìm kiếm regex văn bản siêu phàm
Christian Noel

5

Điều này làm việc cho tôi bằng cách sử dụng sed [ Chỉnh sửa: bình luận bên dưới chỉ ra sed không hỗ trợ \ s]

[^ ]

trong khi

[^\s] 

không

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

echo "ghai ghai" | sed "s/[^ g]//g"
g g

3
\sphù hợp hơn với ký tự khoảng trắng. Nó bao gồm TAB, ký tự xuống dòng của nguồn cấp dữ liệu và những thứ khác (bao nhiêu cái khác tùy thuộc vào hương vị regex). Đó là một phát minh của Perl, ban đầu là cách viết tắt của lớp ký tự POSIX [:space:]và không được hỗ trợ sed. Regex đầu tiên của bạn ở trên phải là s/[^[:space:]g]//g.
Alan Moore

Yup @AlanMoore hoạt động: echo "ghai ghai" | sed "s/[^[:space:]g]//g" Sản lượng:g g
storm_m2138

1

Trên hệ thống của tôi: CentOS 5

Tôi có thể sử dụng \sbên ngoài bộ sưu tập nhưng phải sử dụng [:space:]bên trong bộ sưu tập. Trong thực tế, tôi chỉ có thể sử dụng các [:space:]bộ sưu tập bên trong. Vì vậy, để phù hợp với một không gian duy nhất bằng cách sử dụng này, tôi phải sử dụng [[:space:]] Đó là thực sự kỳ lạ.

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

Result: a b cX
  • không gian đầu tiên tôi phù hợp với \s
  • không gian thứ hai mà tôi so khớp với [[:space:]]
  • trận đấu thứ XI với "tất cả trừ khoảng trống" [^[:space:]]

Hai điều này sẽ không hoạt động:

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

a[^\s]b      instead use a[^[:space:]]b

1
Đối với sed 4.4, rõ ràng là bạn vẫn phải sử dụng ([^[:space:]])thay thế ([^\s]). Tôi đang ở trên openSUSE Tumbleweed 2018 04 03.
user2394284 06/04
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.