Sự khác biệt giữa \ b và \ B trong regex


103

Tôi đang đọc một cuốn sách về biểu thức chính quy và tôi đã xem qua ví dụ này cho \b:

Con mèo vương vãi thức ăn ra khắp phòng.

Sử dụng regex - \bcat\bsẽ phù hợp với từ catnhưng không phải là cattrong scattered.

Đối với \Btác giả sử dụng ví dụ sau:

Vui lòng nhập id gồm chín chữ số như nó

xuất hiện trên mật mã màu của bạn.

Sử dụng \B-\Bkết hợp regex -giữa các từ color - coded. \b-\bMặt khác, sử dụng khớp với -in nine-digitpass-key.

Làm thế nào mà trong ví dụ đầu tiên chúng ta sử dụng \bđể tách biệt catvà trong lần sử dụng thứ hai \Bđể tách biệt -? Sử dụng \btrong ví dụ thứ hai làm ngược lại với những gì nó đã làm trước đó.

Vui lòng giải thích sự khác biệt cho tôi.

EDIT: Ngoài ra, bất cứ ai có thể vui lòng giải thích với một ví dụ mới?

Câu trả lời:


84

Sự nhầm lẫn bắt nguồn từ việc suy nghĩ của bạn \bkhớp với khoảng trắng (có thể vì "b" gợi ý "trống").

\bkhớp với chuỗi trống ở đầu hoặc cuối một từ . \Bkhớp với chuỗi trống không ở đầu hoặc cuối của một từ. Chìa khóa ở đây là "-" không phải là một phần của từ. So <left>-<right>khớp \b-\bvì có các ranh giới từ ở hai bên của -. Mặt khác đối với <left> - <right>(lưu ý khoảng trắng), không có ranh giới từ ở hai bên của dấu gạch ngang. Các ranh giới từ là một dấu cách xa hơn trái và phải.

Mặt khác, khi tìm kiếm các \bcat\branh giới từ hành xử trực quan hơn và nó khớp với "cat" như mong đợi.


2
Vâng, tôi thực sự đã nhầm lẫn \ b với một khoảng trống. Tuy nhiên, tôi vẫn cảm thấy hơi bối rối. Tôi có thể hỏi bạn một ví dụ nữa không?
stiren,

3
Điều quan trọng là nó -không được coi là một phần của một từ. Tương tự, !không phải là một phần của từ. Vì vậy, một lần nữa \b!\bđối sánh với "uunet! Iamold", nhưng không khớp với "Chà! Bạn đúng". Bạn có thể thử công cụ này tại regexpal.com .
andrewdski

@andrewdski Trong trường hợp của tôi \ b cũng bắt được dấu chấm câu ... Tôi đã thử với \ b [A-Z0-9] + \ b trên 1987894, 3219800; 234.567, 345261. và nó hoạt động tốt, tôi có được chỉ số
gunzapper

1
Chỉ cần thêm rằng một tác phẩm bằng regex bao gồm các chữ cái (a– z và A– Z), các chữ số và “_” [gạch dưới]). Mọi thứ khác không phải là từ ngữ.
Maralc

Ai đó có thể giải thích dòng này không\B matches the empty string not at the beginning or end of a word
Arun Gowda

68

\blà một ranh giới từ có độ rộng bằng không. Đặc biệt:

Đối sánh tại vị trí giữa một ký tự từ (bất kỳ ký tự nào khớp với \ w) và một ký tự không phải từ (bất kỳ ký tự nào khớp với [^ \ w] hoặc \ W) cũng như ở đầu và / hoặc cuối chuỗi nếu là ký tự đầu tiên và / hoặc các ký tự cuối cùng trong chuỗi là các ký tự từ.

Ví dụ: .\bkhớp ctrongabc

\Blà ranh giới không từ có độ rộng bằng 0. Đặc biệt:

Khớp ở vị trí giữa hai ký tự từ (tức là vị trí giữa \ w \ w) cũng như ở vị trí giữa hai ký tự không phải từ (tức là \ W \ W).

Ví dụ: \B.\Bkhớp btrongabc

Xem thường- expressions.info để biết thêm thông tin regex tuyệt vời


10
+1 vì chiều rộng bằng không là một phần quan trọng của định nghĩa. Nếu nó không phải là zero-width, thì nó cũng sẽ lấy các ký tự từ / không phải từ đó trong phần khớp của mẫu.
Ben Hocking

5
Nói cách khác, \ B khớp với vị trí giữa \ W và \ W hoặc giữa \ w và \ w, nhưng không khớp với \ W và \ w.

1
Câu trả lời này đã được thêm vào Câu hỏi thường gặp về Cụm từ Thông dụng Stack Overflow , trong "Neo".
aliteralmind

1
@stephenhuh string.match()chỉ trả về trận đấu đầu tiên, trừ khi bạn thêm cờ toàn cầug : "abc def".match(/\b./g)return['a', ' ', 'd']
Bohemian

1
Tôi nghĩ đây là câu trả lời tốt hơn. Tôi cũng nên là người được chấp nhận vì nó giải quyết được sự nhầm lẫn. Nhiều hơn nữa để tìm hiểu ở đây.
Wolf

37

Với một ví dụ khác:

Hãy coi đây là chuỗi và mẫu được tìm kiếm là 'cat':

text = "catmania thiscat thiscatmaina";

Bây giờ là định nghĩa,

'\ b' tìm / khớp với mẫu ở đầu hoặc cuối mỗi từ.

'\ B' không tìm thấy / khớp với mẫu ở đầu hoặc cuối mỗi từ.

Các trường hợp khác nhau:

Trường hợp 1: Ở đầu mỗi từ

result = text.replace(/\bcat/g, "ct");

Bây giờ, kết quả là "ctmania thiscat thiscatmaina"

Trường hợp 2: Cuối mỗi từ

result = text.replace(/cat\b/g, "ct");

Bây giờ, kết quả là "catmania thisct thiscatmaina"

Trường hợp 3: Không phải ngay từ đầu

result = text.replace(/\Bcat/g, "ct");

Bây giờ, kết quả là "catmania thisct thisctmaina"

Trường hợp 4: Cuối cùng thì không

result = text.replace(/cat\B/g, "ct");

Bây giờ, kết quả là "ctmania thiscat thisctmaina"

Trường hợp 5: Không bắt đầu cũng không kết thúc

result = text.replace(/\Bcat\B/g, "ct");

Bây giờ, kết quả là "catmania thiscat thisctmaina"

Hi vọng điêu nay co ich :)


Vui lòng sửa cho tôi nếu tôi sai, nhưng khi sử dụng \ bcat \ b, nếu chuỗi của chúng tôi sẽ là, ví dụ: "catcat is my cat" => từ đầu tiên (catcat) sẽ áp dụng cho điều kiện này. Không?.
Kosem

8

Metacharacter \ b là một mỏ neo giống như dấu mũ và ký hiệu đô la. Nó khớp ở một vị trí được gọi là "ranh giới từ". Trận đấu này có độ dài bằng 0.

Có ba vị trí khác nhau đủ điều kiện làm ranh giới từ:

  • Trước ký tự đầu tiên trong chuỗi, nếu ký tự đầu tiên là ký tự từ.
  • Sau ký tự cuối cùng trong chuỗi, nếu ký tự cuối cùng là ký tự từ.
  • Giữa hai ký tự trong chuỗi, trong đó một ký tự là từ và ký tự kia không phải là ký tự từ.

\ B là phiên bản phủ định của \ b . \ B khớp ở mọi vị trí mà \ b không khớp. Thực tế, \ B khớp ở bất kỳ vị trí nào giữa hai ký tự từ cũng như ở bất kỳ vị trí nào giữa hai ký tự không phải từ.

Nguồn: http://www.regular-expressions.info/wordboundaries.html


3

\bkhớp với ranh giới từ. \Bkhớp với các ranh giới không phải từ và tương đương với (cảm ơn @Alan Moore đã chỉnh sửa!) . Cả hai đều có chiều rộng bằng không.[^\b](?!\b)

Xem http://www.regular-expressions.info/wordboundaries.html để biết chi tiết. Trang web cực kỳ hữu ích cho nhiều câu hỏi regex cơ bản.


4
\Bkhông tương đương với [^\b]. Một lớp ký tự ( [...]hoặc [^...]) sử dụng chính xác một ký tự, trong khi các xác nhận có độ rộng bằng 0 thích \b\Bkhông sử dụng bất kỳ thứ gì. Nếu bạn đặt \bvào một lớp ký tự, nó mang một ý nghĩa hoàn toàn khác: [\b]khớp với một dấu cách lùi và [^\b]khớp với bất kỳ ký tự nào ngoại trừ một dấu cách lùi. \Bthực sự tương đương với (?!\b).
Alan Moore

@Alan cảm ơn, bạn hoàn toàn chính xác - tôi đã không thức sáng nay khi tôi viết điều đó. Đã sửa.
Matt Ball

4
... nhưng tại sao bất kỳ ai cũng muốn khớp với một backspace thì ngoài tôi. : D
Alan Moore

1

Hãy lấy một chuỗi như:

XIX IXI XX XI II IIXX XXII II XX -X X- XI IX -X- -IX -XI IX- XI- X_X _X-

Lưu ý: Dấu gạch dưới (_) không được coi là ký tự đặc biệt trong trường hợp này.

  1. /\bX\b/g Nên bắt đầu và kết thúc bằng một ký tự đặc biệt hoặc dấu cách trắng

XIX IXI XX X I II IIXX XXII II X - X - X X - X -I I- X - X - -I- X - X -I I- X - X -I- X_X _X-


  1. /\bX/g Nên bắt đầu bằng một ký tự đặc biệt hoặc khoảng trắng

X IX IXI X X X I II IIXX X XII II X - X - X X - X -I I- X - X - -I- X - X -I I- X - X -I- X _X _X-


  1. /X\b/g Nên kết thúc bằng ký tự đặc biệt hoặc khoảng trắng

XI X IXI X X X I II IIX X XXII II X - X - X X - X -I I- X - X - -I- X - X -I I- X - X -I- X_ X _ X -


  1. /\BX\B/g
    Nên không bắt đầu và không kết thúc với một ký tự đặc biệt hoặc không gian trắng

XIX I X I XX XI II II X X X X II II XX -X X- XI IX -X- -IX -XI IX- XI- X_X _X-


  1. /\BX/gNên không bắt đầu với một ký tự đặc biệt hoặc không gian trắng

XI X I X I X X XI II II XX X X II II XX -X X- XI IX -X- -IX -XI IX- XI- X_ X _ X -


  1. /X\B/gNên không kết thúc với một ký tự đặc biệt hoặc không gian trắng

X IX I X I X X XI II II X X XX II II XX -X X- XI IX -X- -IX -XI IX- XI- X _X _X-


  1. /\bX\B/gNên bắt đầu và không kết thúc bằng ký tự đặc biệt hoặc dấu cách trắng

X IX IXI X X XI II II X X X XII II XX -X X- XI IX -X- -IX -XI IX- XI- X _X _X-


  1. /\BX\b/gNên không bắt đầu và sẽ kết thúc với một ký tự đặc biệt hoặc không gian trắng

XI X IXI X X XI II IIX X XXII II XX -X X- XI IX -X- -IX -XI IX- XI- X_ X _ X -


1

Nguồn © Bản quyền RexEgg.com

Ranh giới từ: \ b *

Ranh giới từ \ b khớp với các vị trí mà một bên là ký tự từ (thường là chữ cái, chữ số hoặc dấu gạch dưới — nhưng xem bên dưới để biết các biến thể giữa các công cụ) và bên kia không phải là ký tự từ (ví dụ: nó có thể là đầu của chuỗi hoặc một ký tự khoảng trắng).

Do đó, regex \ bcat \ b sẽ so khớp mèo với mèo đen, nhưng sẽ không khớp với catatonic, tomcat hoặc chứng chỉ. Xóa một trong các ranh giới, \ bcat sẽ khớp với cat trong catfish và cat \ b sẽ khớp với cat trong tomcat, nhưng không phải ngược lại. Tất nhiên, cả hai sẽ tự khớp với mèo.

Không-một-từ-ranh giới: \ B

\ B khớp với tất cả các vị trí mà \ b không khớp. Do đó, nó phù hợp với:

✽ Khi không bên nào là ký tự từ, chẳng hạn ở bất kỳ vị trí nào trong chuỗi $ = (@ -% ++) (bao gồm cả phần đầu và phần cuối của chuỗi)

✽ Khi cả hai bên là một ký tự từ, chẳng hạn giữa chữ H và chữ i trong Hi!

Điều này có vẻ không hữu ích lắm, nhưng đôi khi \ B chính là thứ bạn muốn. Ví dụ,

✽ \ Bcat \ B sẽ tìm thấy con mèo được bao quanh đầy đủ bởi các ký tự từ, như trong chứng chỉ, nhưng không phải của riêng nó cũng như ở đầu hoặc cuối từ.

✽ cat \ B sẽ tìm thấy cat trong cả giấy chứng nhận và catfish, nhưng không phải trong tomcat cũng như trên chính nó.

✽ \ Bcat sẽ tìm thấy con mèo trong cả chứng chỉ và tomcat, nhưng không phải trong cá da trơn cũng như của riêng nó.

✽ \ Bcat | cat \ B sẽ tìm thấy con mèo trong tình huống được nhúng, ví dụ như trong chứng chỉ, cá da trơn hoặc tomcat, nhưng không phải của riêng nó.


1

\ b được sử dụng làm ranh giới từ

word = "categorical cat"

Tìm tất cả "cat" trong từ trên

không có \ b

re.findall(r'cat',word)
['cat', 'cat']

với B

re.findall(r'\bcat\b',word)
['cat']

0

\Bđược không \b ví dụ tiêu cực \b

pass-keyở đây không có ranh giới từ bên cạnh -vì vậy nó khớp \Btrong ví dụ đầu tiên của bạn, có ranh giới từ bên cạnh mèo nên nó khớp\b

các quy tắc tương tự cũng áp dụng cho những người khác. \Wlà phủ định của \w \UPPER CASElà phủ định của\LOWER CASE

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.