Làm cách nào để bỏ qua khoảng trắng trong chuỗi chủ đề biểu thức chính quy?


107

Có cách nào đơn giản để bỏ qua khoảng trắng trong chuỗi đích khi tìm kiếm các kết quả phù hợp bằng cách sử dụng mẫu biểu thức chính quy không? Ví dụ: nếu tìm kiếm của tôi là "mèo", tôi muốn "c ats" hoặc "ca ts" phải khớp. Tôi không thể loại bỏ khoảng trắng trước vì tôi cần tìm chỉ mục bắt đầu và kết thúc của kết quả khớp (bao gồm bất kỳ khoảng trắng nào) để đánh dấu kết quả khớp đó và bất kỳ khoảng trắng nào cũng cần có ở đó cho mục đích định dạng.

Câu trả lời:


124

Bạn có thể dán các ký tự khoảng trắng tùy chọn \s*vào giữa mọi ký tự khác trong regex của mình. Mặc dù được cấp phép, nhưng nó sẽ hơi dài dòng.

/cats/ -> /c\s*a\s*t\s*s/


Cảm ơn, có vẻ như đó là cách để đi. Nhưng tôi chỉ nhận ra rằng tôi chỉ muốn các ký tự khoảng trắng tùy chọn nếu chúng theo dòng mới. Vì vậy, ví dụ: "c \ n ats" hoặc "ca \ n ts" phải khớp. Nhưng sẽ không muốn "c ats" khớp nếu không có dòng mới. Bất kỳ ý tưởng về cách điều đó có thể được thực hiện?
Steven

@Steven, hãy xem cách tôi đã làm dưới đây, bạn có thể dễ dàng điều chỉnh giải pháp của tôi cho những trường hợp cụ thể như vậy.
Bob

@ Chris Tôi nghĩ rằng, regex này là rất nghiêm ngặt cho mèo mà thôi, nó cũng có thể được viết cho bất kỳ tìm kiếm các chữ cái như thế này: ^([a-z]\s*)+$
Sandeep Kaur

9

Giải quyết bình luận của Steven cho câu trả lời của Sam Dufel

Cảm ơn, có vẻ như đó là cách để đi. Nhưng tôi chỉ nhận ra rằng tôi chỉ muốn các ký tự khoảng trắng tùy chọn nếu chúng theo dòng mới. Vì vậy, ví dụ: "c \ n ats" hoặc "ca \ n ts" phải khớp. Nhưng sẽ không muốn "c ats" khớp nếu không có dòng mới. Bất kỳ ý tưởng về cách điều đó có thể được thực hiện?

Cái này cần phải dùng mẹo:

/c(?:\n\s*)?a(?:\n\s*)?t(?:\n\s*)?s/

Xem trang này để biết tất cả các biến thể khác nhau của 'mèo' phù hợp với trang này.

Bạn cũng có thể giải quyết vấn đề này bằng cách sử dụng các điều kiện , nhưng chúng không được hỗ trợ trong hương vị javascript của regex.


3
Vì vậy, rất xấu xí. Phải có cách tốt hơn.
james.garriss

Bạn có thể làm cho nó dễ đọc hơn trong cú pháp JS (mặc dù kỹ thuật này sẽ làm việc trong các ngôn ngữ khác) với:new RegExp('cats'.split('').join('(?:\n\s*)?'))
brianary

7

Mặc dù câu trả lời được chấp nhận là đúng về mặt kỹ thuật, nhưng một cách tiếp cận thực tế hơn, nếu có thể, là chỉ xóa khoảng trắng ra khỏi cả biểu thức chính quy và chuỗi tìm kiếm.

Nếu bạn muốn tìm kiếm "mèo của tôi", thay vì:

myString.match(/m\s*y\s*c\s*a\*st\s*s\s*/g)

Cứ làm đi:

myString.replace(/\s*/g,"").match(/mycats/g)

Cảnh báo: Bạn không thể tự động hóa việc này trên biểu thức chính quy bằng cách chỉ thay thế tất cả các khoảng trắng bằng các chuỗi trống vì chúng có thể xảy ra trong một phủ định hoặc làm cho biểu thức chính quy của bạn không hợp lệ.


5

Bạn có thể đặt \s*vào giữa mọi ký tự trong chuỗi tìm kiếm của mình, vì vậy nếu bạn đang tìm kiếm mèo, bạn sẽ sử dụngc\s*a\s*t\s*s\s*s

Nó dài nhưng tất nhiên bạn có thể xây dựng chuỗi động.

Bạn có thể thấy nó hoạt động tại đây: http://www.rubular.com/r/zzWwvppSpE


3

Nếu bạn chỉ muốn cho phép khoảng trắng, thì

\bc *a *t *s\b

Hãy làm nó. Để cũng cho phép các tab, hãy sử dụng

\bc[ \t]*a[ \t]*t[ \t]*s\b

Bỏ dấu \bneo nếu bạn cũng muốn tìm catstrong các từ như bobcatshoặc catsup.


1

Cách tiếp cận này có thể được sử dụng để tự động hóa việc này (giải pháp mẫu sau đây là trong python, mặc dù rõ ràng nó có thể được chuyển sang bất kỳ ngôn ngữ nào):

bạn có thể loại bỏ khoảng trắng trước VÀ lưu vị trí của các ký tự không phải khoảng trắng để bạn có thể sử dụng chúng sau này để tìm ra vị trí ranh giới của chuỗi đã khớp trong chuỗi gốc như sau:

def regex_search_ignore_space(regex, string):
    no_spaces = ''
    char_positions = []

    for pos, char in enumerate(string):
        if re.match(r'\S', char):  # upper \S matches non-whitespace chars
            no_spaces += char
            char_positions.append(pos)

    match = re.search(regex, no_spaces)
    if not match:
        return match

    # match.start() and match.end() are indices of start and end
    # of the found string in the spaceless string
    # (as we have searched in it).
    start = char_positions[match.start()]  # in the original string
    end = char_positions[match.end()]  # in the original string
    matched_string = string[start:end]  # see

    # the match WITH spaces is returned.
    return matched_string

with_spaces = 'a li on and a cat'
print(regex_search_ignore_space('lion', with_spaces))
# prints 'li on'

Nếu bạn muốn đi xa hơn, bạn có thể xây dựng đối tượng khớp và trả về thay thế, vì vậy việc sử dụng trình trợ giúp này sẽ tiện dụng hơn.

Và hiệu suất của chức năng này tất nhiên cũng có thể được tối ưu hóa, ví dụ này chỉ là để hiển thị đường dẫn đến một giải pháp.

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.