Biểu thức regex trong Java, \\ s so với \\ s +


96

Sự khác biệt giữa hai biểu thức sau đây là gì?

x = x.replaceAll("\\s", "");
x = x.replaceAll("\\s+", "");

3
Các bộ định lượng, hãy đọc chúng.
jn1kk

Câu trả lời:


88

Cái đầu tiên khớp với một khoảng trắng, trong khi cái thứ hai khớp với một hoặc nhiều khoảng trắng. Chúng được gọi là bộ định lượng biểu thức chính quy và chúng thực hiện các kết quả khớp như thế này (lấy từ tài liệu ):

Greedy quantifiers
X?  X, once or not at all
X*  X, zero or more times
X+  X, one or more times
X{n}    X, exactly n times
X{n,}   X, at least n times
X{n,m}  X, at least n but not more than m times

Reluctant quantifiers
X?? X, once or not at all
X*? X, zero or more times
X+? X, one or more times
X{n}?   X, exactly n times
X{n,}?  X, at least n times
X{n,m}? X, at least n but not more than m times

Possessive quantifiers
X?+ X, once or not at all
X*+ X, zero or more times
X++ X, one or more times
X{n}+   X, exactly n times
X{n,}+  X, at least n times
X{n,m}+ X, at least n but not more than m times

20
Tôi luôn thích cách họ cung cấp các mô tả riêng biệt về các phiên bản tham lam, miễn cưỡng và chiếm hữu của mỗi bộ định lượng, và sau đó nói chính xác điều giống nhau về cả ba. ;)
Alan Moore

60

Hai replaceAllcuộc gọi đó sẽ luôn tạo ra cùng một kết quả, bất kể là gì x. Tuy nhiên, điều quan trọng cần lưu ý là hai biểu thức chính quy không giống nhau:

  • \\s - khớp với một ký tự khoảng trắng
  • \\s+ - đối sánh chuỗi một hoặc nhiều ký tự khoảng trắng.

Trong trường hợp này, nó không có gì khác biệt, vì bạn đang thay thế mọi thứ bằng một chuỗi rỗng (mặc dù sẽ tốt hơn nếu sử dụng \\s+theo quan điểm hiệu quả). Nếu bạn thay thế bằng một chuỗi không rỗng, cả hai sẽ hoạt động khác nhau.


Viết dòng đầu tiên của bạn, Nếu x là "Đặt tên miền của bạn và nhận \ n \ n \ n \ n \ n \ n Trực tuyến ngay hôm nay." Cả hai sẽ tạo ra kết quả giống nhau?
sofs1 15/12/16

3
@ user3705478 Cả hai sẽ cho kết quả giống nhau, ngay cả khi có nhiều dấu cách sau nhau. Sự khác biệt nằm ở cách nó được xử lý. Nếu bạn có một nhóm (ví dụ) 3 dấu cách trực tiếp theo sau nhau \\ s + sẽ lấy nhóm đó và biến toàn bộ nó thành "", trong khi \\ s sẽ tự xử lý mọi khoảng trắng.
Dennie

11

Trước hết, bạn cần hiểu rằng đầu ra cuối cùng của cả hai câu lệnh sẽ giống nhau, tức là loại bỏ tất cả các khoảng trắng khỏi chuỗi đã cho.

Tuy nhiên, x.replaceAll("\\s+", "");sẽ là cách hiệu quả hơn để cắt bỏ các khoảng trắng (nếu chuỗi có thể có nhiều khoảng trắng liền nhau) vì có khả năng ít thay thế hơn do thực tế là regex \\s+khớp với 1 hoặc nhiều khoảng trắng cùng một lúc và thay thế chúng bằng chuỗi trống.

Vì vậy, mặc dù bạn nhận được cùng một đầu ra từ cả hai, tốt hơn nên sử dụng:

x.replaceAll("\\s+", "");

2

Regex đầu tiên sẽ khớp với một ký tự khoảng trắng. Regex thứ hai sẽ miễn cưỡng khớp với một hoặc nhiều ký tự khoảng trắng. Đối với hầu hết các mục đích, hai regex này rất giống nhau, ngoại trừ trường hợp thứ hai, regex có thể khớp với nhiều chuỗi hơn, nếu nó ngăn không cho khớp regex không thành công. từ http://www.coderanch.com/t/570917/java/java/regex-difference


Cào từ "bất đắc dĩ". Câu hỏi này là về \s+, không \s+?giống như câu hỏi khác.
Alan Moore
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.