2009-02-08 19 views
34

Cụm từ thông dụng có thể khớp với khoảng trắng hoặc bắt đầu chuỗi không?Cụm từ thông dụng: bắt đầu hoặc khoảng trắng phù hợp

Tôi đang cố thay thế đơn vị tiền tệ viết tắt GBP bằng ký hiệu £. Tôi chỉ có thể phù hợp với bất cứ điều gì bắt đầu từ GBP, nhưng tôi muốn được bảo thủ hơn một chút, và tìm một số dấu phân cách xung quanh nó.

>>> import re 
>>> text = u'GBP 5 Off when you spend GBP75.00' 

>>> re.sub(ur'GBP([\W\d])', ur'£\g<1>', text) # matches GBP with any prefix 
u'\xa3 5 Off when you spend \xa375.00' 

>>> re.sub(ur'^GBP([\W\d])', ur'£\g<1>', text) # matches at start only 
u'\xa3 5 Off when you spend GBP75.00' 

>>> re.sub(ur'(\W)GBP([\W\d])', ur'\g<1>£\g<2>', text) # matches whitespace prefix only 
u'GBP 5 Off when you spend \xa375.00' 

Tôi có thể làm cả hai ví dụ sau cùng một lúc?

+0

Ngôn ngữ nào? Có phải Perl không? –

+0

Python. –

+0

Có Python, nhưng khái niệm là như nhau bất kể. – Mat

Trả lời

38

Sử dụng OR "|" điều hành:

>>> re.sub(r'(^|\W)GBP([\W\d])', u'\g<1>£\g<2>', text) 
u'\xa3 5 Off when you spend \xa375.00' 
+1

Tuyệt vời. Tôi cho rằng ... đã buộc phải ở ngay đầu của chuỗi. Thay đổi nhỏ cần thiết để duy trì khoảng cách: re.sub (u '(^ | \ W) GBP ([\ W \ d])', u '\ g <1> £ \ g <2>', văn bản). Được chấp nhận do là giải pháp trực quan nhất cho vấn đề trước mắt của tôi. – Mat

+0

@Mat: Cảm ơn, tôi đã cập nhật câu trả lời của tôi như được đề xuất. –

24

\b là ranh giới từ, có thể là khoảng trắng, đầu dòng hoặc ký hiệu không phải là chữ số và chữ số (\bGBP\b).

+1

Tuyệt. Tôi đã học được hai điều từ câu trả lời của bạn.1. Tôi chưa bao giờ sử dụng ranh giới từ trong các biểu thức chính quy trước đây. 2. Mọi thứ (đặc biệt là \ b) không hoạt động tốt nếu bạn vô tình sử dụng các tiền tố u '' thay vì r '' trên các biểu thức chính quy của Python. – Mat

+0

@Mat: Tất nhiên bạn có thể sử dụng ur "myregex" – nosklo

+0

Cool. Điều đó có ý nghĩa bây giờ bạn đề cập đến nó. – Mat

1

Có, tại sao không?

re.sub(u'^\W*GBP... 

phù hợp với sự khởi đầu của chuỗi, 0 hoặc nhiều khoảng trắng, sau đó GBP ...

chỉnh sửa: Ồ, tôi nghĩ rằng bạn muốn thay đổi luân phiên, sử dụng |:

re.sub(u'(^|\W)GBP... 
0

Bạn luôn có thể cắt khoảng trắng đầu và cuối từ mã thông báo trước khi bạn tìm kiếm nếu đó không phải là tình huống phù hợp/nhóm mà yêu cầu dòng đầy đủ.

6

này thay thế GBP nếu nó trước bởi sự bắt đầu của một chuỗi hoặc một word boundary (mà sự bắt đầu của một chuỗi đã có), và sau GBP đến một giá trị số hoặc một ranh giới từ:

re.sub(u'\bGBP(?=\b|\d)', u'£', text) 

này loại bỏ sự cần thiết cho bất kỳ backreferencing không cần thiết bằng cách sử dụng một lookahead. Bao gồm đủ?

+0

"\ d +": dấu cộng là không cần thiết – tzot

+0

Bạn nói đúng, trên thực tế hầu hết các công cụ regex không cho phép lặp lại hoặc chỉ một số mố lặp cố định {MIN, MAX} bên trong các kết quả làm cho \ d + không hợp lệ. Tôi đã nhận thức nhưng hoàn toàn bỏ lỡ nó vì vậy nhờ tôi đã chỉnh sửa cho phù hợp :) –

+0

@ Martart, mà chỉ áp dụng cho lookBEHINDs; lookAHEADs không có giới hạn như vậy (ít nhất, không có bất kỳ hương vị nào mà tôi quen thuộc). –

2

Tôi nghĩ rằng bạn đang tìm kiếm '(^|\W)GBP([\W\d])'

0

Nó hoạt động trong Perl:

$text = 'GBP 5 off when you spend GBP75'; 
$text =~ s/(\W|^)GBP([\W\d])/$1\$$2/g; 
printf "$text\n"; 

Đầu ra là:

$ 5 off when you spend $75 

Lưu ý rằng tôi đã quy định rằng trận đấu phải là toàn cầu, để có được tất cả các lần xuất hiện.

Các vấn đề liên quan