Regex chỉ đối sánh toàn bộ từ


90

Tôi có một biểu thức regex mà tôi đang sử dụng để tìm tất cả các từ trong một khối nội dung nhất định, không phân biệt chữ hoa chữ thường, được chứa trong bảng thuật ngữ được lưu trữ trong cơ sở dữ liệu. Đây là mẫu của tôi:

/($word)/i

Vấn đề là, nếu tôi sử dụng /(Foo)/ithì những từ như Foodđược kết hợp. Cần có khoảng trắng hoặc ranh giới từ ở cả hai mặt của từ.

Làm cách nào để tôi có thể sửa đổi biểu thức của mình để chỉ khớp với từ Fookhi đó là một từ ở đầu, giữa hoặc cuối câu?

Câu trả lời:


120

Sử dụng ranh giới từ:

/\b($word)\b/i

Hoặc nếu bạn đang tìm kiếm "SPECTRE" như trong ví dụ của Sinan Ünür:

/(?:\W|^)(\Q$word\E)(?:\W|$)/i

1
Tôi chỉ đang gõ phiên bản dài của câu trả lời này khi bạn đăng. :)
ZombieSheep

@RichardSimoes \b(<|>=)\bkhông phù hợp>=
alhelal

@RichardSimoes và \b[-|+][0-9]+\bkhớp +10trong 43E+10. Cả hai tôi đều không muốn.
alhelal

điều gì sẽ xảy ra nếu tôi muốn tìm kiếm từ không được thêm vào hoặc không có trong bất kỳ từ nào khác. sau đó logic này sẽ không hoạt động
Prasanna Sasne

Làm thế nào để ai đó có được các toán tử so sánh toán học> = và <=?
AntonSack

50

Để đối sánh toàn bộ từ, bạn sẽ sử dụng mẫu (\w+)

Giả sử bạn đang sử dụng PCRE hoặc thứ gì đó tương tự:

nhập mô tả hình ảnh ở đây

Ảnh chụp màn hình phía trên được lấy từ ví dụ trực tiếp này: http://regex101.com/r/cU5lC2

Đối sánh toàn bộ từ trên dòng lệnh với (\w+)

Tôi sẽ sử dụng trình bao tương tác phpsh trên Ubuntu 12.10 để trình diễn công cụ regex PCRE thông qua phương pháp gọi là preg_match

Bắt đầu phpsh, đặt một số nội dung vào một biến, khớp trên word.

el@apollo:~/foo$ phpsh

php> $content1 = 'badger'
php> $content2 = '1234'
php> $content3 = '$%^&'

php> echo preg_match('(\w+)', $content1);
1

php> echo preg_match('(\w+)', $content2);
1

php> echo preg_match('(\w+)', $content3);
0

Phương pháp preg_match sử dụng động cơ PCRE trong ngôn ngữ PHP để phân tích biến: $content1, $content2$content3với các (\w)+mô hình.

$ content1 và $ content2 chứa ít nhất một từ, $ content3 thì không.

Ghép một số từ theo nghĩa đen trên dòng lệnh với (dart|fart)

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(dart|fart)', $gun1);
1

php> echo preg_match('(dart|fart)', $gun2);
1

php> echo preg_match('(dart|fart)', $gun3);
1

php> echo preg_match('(dart|fart)', $gun4);
0

biến gun1 và gun2 chứa chuỗi phi tiêu hoặc xì hơi. gun4 không. Tuy nhiên, nó có thể là một vấn đề khi tìm kiếm từfart phù hợp farty. Để khắc phục điều này, hãy thực thi ranh giới từ trong regex.

Ghép các từ theo nghĩa đen trên dòng lệnh với các ranh giới từ.

el@apollo:~/foo$ phpsh

php> $gun1 = 'dart gun';
php> $gun2 = 'fart gun';
php> $gun3 = 'farty gun';
php> $gun4 = 'unicorn gun';

php> echo preg_match('(\bdart\b|\bfart\b)', $gun1);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun2);
1

php> echo preg_match('(\bdart\b|\bfart\b)', $gun3);
0

php> echo preg_match('(\bdart\b|\bfart\b)', $gun4);
0

Vì vậy, nó giống như các ví dụ trước ngoại trừ các từ fartvới một \branh giới từ không tồn tại trong nội dung: farty.


sáng, chiều không phải là lời nói?
minion

Nếu bạn muốn buộc am và pm là các từ, (không phải, chúng là từ viết tắt) thì hãy thêm dấu chấm làm ký tự từ cho công cụ regex của bạn. Đối với bạn, có vẻ như bạn đã đặt dấu chấm không phải là một ký tự của từ, do đó, các từ regex sẽ không phải là một đối một và phù hợp với định nghĩa tiêu chuẩn của "từ" mà bạn đã được dạy trong Từ điển Châu Âu cho người Châu Âu lai của mình ngôn ngữ (hoặc bất kỳ ngôn ngữ nào khác cho vấn đề đó).
Eric Leschinski

8

Sử dụng \bcó thể mang lại kết quả đáng ngạc nhiên. Tốt hơn hết bạn nên tìm ra điều gì tách một từ khỏi định nghĩa của nó và kết hợp thông tin đó vào mẫu của bạn.

#!/usr/bin/perl

use strict; use warnings;

use re 'debug';

my $str = 'S.P.E.C.T.R.E. (Special Executive for Counter-intelligence,
Terrorism, Revenge and Extortion) is a fictional global terrorist
organisation';

my $word = 'S.P.E.C.T.R.E.';

if ( $str =~ /\b(\Q$word\E)\b/ ) {
    print $1, "\n";
}

Đầu ra:

Biên dịch REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"
Chương trình cuối cùng:
   1: TRÒN (2)
   2: MỞ 1 (4)
   4: CHÍNH XÁC (9)
   9: ĐÓNG1 (11)
  11: TRÒN (12)
  12: HẾT (0)
neo "SPECTRE" ở 0 (kiểm tra được neo) lớp BOUND tối thiểu 14
Đoán trận đấu bắt đầu trong sv cho REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" đấu với "SP
.ECTRE (Điều hành đặc biệt về chống tình báo, "...
Đã tìm thấy con con được cố định "SPECTRE" ở độ lệch 0 ...
start_shift: 0 check_at: 0 s: 0 endpos: 1
Không mâu thuẫn với STCLASS ...
Đã đoán: khớp ở độ lệch 0
Đối sánh REx "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B" với "SPECTRE (Thực thi đặc biệt
utive cho phản tình báo, "...
   0 | 1: TRÒN (2)
   0 | 2: MỞ 1 (4)
   0 | 4: CHÍNH XÁC (9)
  14 | 9: ĐÓNG1 (11)
  14 | 11: TRÒN (12)
                                  thất bại...
Trận đấu không thành công
Giải phóng REx: "\ b (S \ .P \ .E \ .C \ .T \ .R \ .E \.) \ B"

1
Tôi nghĩ một từ thường sẽ là một từ, nhưng điểm thú vị.
Richard Simões

1

sử dụng ranh giới từ \ b,

Sau đây (sử dụng bốn lần thoát) hoạt động trong môi trường của tôi: Mac, safari Phiên bản 10.0.3 (12602.4.8)

var myReg = new RegExp(‘\\\\b’+ variable + ‘\\\\b’, ‘g’)

1

Đối với những người muốn xác thực Enum trong mã của họ, bạn có thể làm theo hướng dẫn

Trong Regex World, bạn có thể sử dụng ^để bắt đầu một chuỗi và $kết thúc nó. Sử dụng chúng kết hợp với |có thể là những gì bạn muốn:

^(Male)$|^(Female)$

Nó sẽ chỉ trả về true cho Malehoặc Femaletrường hợp.


^$khớp với phần đầu (tương ứng với phần cuối) của một dòng, do đó, ví dụ của bạn sẽ chỉ khớp nếu đó là những từ duy nhất trong dòng.
gent

và đây chính xác là những gì tôi muốn khi tôi muốn xác thực một enum! vấn đề là gì
MohamadrezaRahimianGolkhandani

0

Nếu bạn đang làm điều đó trong Notepad ++

[\w]+ 

Sẽ cung cấp cho bạn toàn bộ từ và bạn có thể thêm dấu ngoặc đơn để đặt nó thành một nhóm. Ví dụ: conv1 = Conv2D(64, (3, 3), activation=LeakyReLU(alpha=a), padding='valid', kernel_initializer='he_normal')(inputs). Tôi muốn chuyển LeakyReLUsang dòng riêng của nó dưới dạng nhận xét và thay thế kích hoạt hiện tại. Trong notepad ++, điều này có thể được thực hiện bằng cách sử dụng lệnh tìm sau:

([\w]+)( = .+)(LeakyReLU.alpha=a.)(.+)

và lệnh thay thế trở thành:

\1\2'relu'\4 \n    # \1 = LeakyReLU\(alpha=a\)\(\1\)

Khoảng trống là để giữ đúng định dạng trong mã của tôi. :)


-1

Nhận tất cả các "từ" trong một chuỗi

/([^\s]+)/g

Về cơ bản ^/scó nghĩa là ngắt trên khoảng trắng (hoặc so khớp các nhóm không có khoảng trắng)
Đừng quên gcho Greedy

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.