Biểu thức chính quy để trả về văn bản giữa dấu ngoặc đơn


113
u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'

Tất cả những gì tôi cần là nội dung bên trong dấu ngoặc đơn.


Dấu ngoặc? Tôi không thấy bất kỳ dấu ngoặc nào. Ý bạn là dấu ngoặc đơn?
kzh

4
Tại sao không sử dụng dấu ngoặc kép? Nó sẽ làm cho chuỗi dễ đọc hơn, tức làu"abcde(date='2/xc2/xb2',time='/case/test.png')"
kzh

Câu hỏi này khiến tôi lo lắng khi chỉ nhìn vào nó. Tôi nhận được nghi ngờ lén lút OP thực sự muốn chức năng trong astvà chỉ không biết nó tồn tại.
Kevin

Câu trả lời:


247

Nếu vấn đề của bạn thực sự chỉ đơn giản như vậy, bạn không cần regex:

s[s.find("(")+1:s.find(")")]

9
điều gì xảy ra nếu không có '(' và ')'? bạn sẽ nhận được s [0: -1]. Có nghĩa là bạn sẽ nhận được bất cứ thứ gì trong 's': \. Sẽ rất tốt nếu bạn kiểm tra xem chuỗi có dấu ngoặc đơn trước hay không.
Omar

5
Điều gì sẽ xảy ra nếu bạn có "(một số văn bản (một số văn bản trong ngoặc đơn bên trong) một số văn bản khác)"?
Igor Pomaranskiy

4
Khi đó vấn đề không đơn giản như vấn đề ban đầu và sẽ yêu cầu một giải pháp khác.
tkerwin

1
Đối với câu hỏi của Igor: nếu bạn có dấu ngoặc đơn lồng nhau như vậy, bạn sử dụng rfind cho phần thứ hai của phép toán. Xem bài đăng của tôi dưới đây để biết thêm chi tiết về điều này.
FaustoW 17/02/17

61

Sử dụng re.search(r'\((.*?)\)',s).group(1):

>>> import re
>>> s = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'
>>> re.search(r'\((.*?)\)',s).group(1)
u"date='2/xc2/xb2',time='/case/test.png'"

45

Nếu bạn muốn tìm tất cả các lần xuất hiện:

>>> re.findall('\(.*?\)',s)
[u"(date='2/xc2/xb2',time='/case/test.png')", u'(eee)']

>>> re.findall('\((.*?)\)',s)
[u"date='2/xc2/xb2',time='/case/test.png'", u'eee']

có thể là một câu hỏi ngu ngốc, nhưng tại sao lại là "?" cần thiết? Tại sao "(. *)" Không hoạt động?
CutePoison

3
@CutePoison bởi vì .*tham lam (sẽ có trận đấu lâu nhất) và .*?không tham lam (sẽ có trận đấu ngắn nhất)
dopstar

29

Dựa trên câu trả lời của tkerwin, nếu bạn tình cờ có dấu ngoặc đơn lồng nhau như trong

st = "sum((a+b)/(c+d))"

câu trả lời của anh ấy sẽ không hoạt động nếu bạn cần lấy mọi thứ giữa dấu ngoặc mở đầu tiêndấu ngoặc đóng cuối cùng để lấy (a+b)/(c+d), vì tìm kiếm từ bên trái của chuỗi và sẽ dừng lại ở dấu ngoặc đóng đầu tiên.

Để khắc phục điều đó, bạn cần sử dụng rfindcho phần thứ hai của hoạt động, vì vậy nó sẽ trở thành

st[st.find("(")+1:st.rfind(")")]

1
@ALH rằng biểu thức không có dấu ngoặc đơn lồng nhau , đó là điều mà câu trả lời của tôi phù hợp.
FaustoW

6
import re

fancy = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'

print re.compile( "\((.*)\)" ).search( fancy ).group( 1 )

2
contents_re = re.match(r'[^\(]*\((?P<contents>[^\(]+)\)', data)
if contents_re:
    print(contents_re.groupdict()['contents'])

Mặc dù mã này có thể trả lời câu hỏi, nhưng việc cung cấp ngữ cảnh bổ sung về cách và / hoặc lý do tại sao nó giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời
sshashank124
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.