2010-03-04 27 views
6

Tôi đang cố gắng tìm ra cách tốt nhất để làm điều này ...chuỗi tách đặc biệt trong Ruby

Cho một xâu

s = "if someBool || x==1 && y!=22314" 

Tôi muốn sử dụng Ruby để tách các báo cáo và các toán tử logic .. vì vậy tôi muốn chia này vào

["if","someBool","||","x","==","1","&&","y","!=","22314"] 

tôi có thể sử dụng s.split(), nhưng chỉ chia tách này với không gian như delimeters..but tôi muốn x! = y để được chia quá (chúng là các câu boolean hợp lệ, chúng chỉ không có không gian ở giữa để dễ đọc). Tất nhiên cách dễ nhất là yêu cầu người dùng đặt không gian giữa toán tử boolean và các biến, nhưng có cách nào khác để làm điều này không?

Trả lời

4

chia vào khoảng trắng hoặc một ranh giới từ:

s = "if someBool || x==1 && y!=22314" 
a = s.split(/\s+|\b/); 
p a 

Output:

["if", "someBool", "||", "x", "==", "1", "&&", "y", "!=", "22314"] 
+0

Đúng, điều đó có thể xảy ra với tôi. Tốt đẹp. – Shadowfirebird

1

Bạn có thể chia tách để chia nhỏ mọi thứ bạn muốn, bao gồm cả regex. Một cái gì đó như:

s.split(/\s|==|!=/) 

... có thể là khởi đầu.

Tuyên bố từ chối trách nhiệm: regexen khiến đầu tôi đau. Tôi đã thử nghiệm nó ngay bây giờ, và nó hoạt động dựa trên ví dụ của bạn.


CẬP NHẬT: Không có. chia luôn luôn bỏ qua những gì nó chia tách trên, vì vậy mã trên mất == và! = từ ví dụ của bạn. (Mã của Monoceres hoạt động tốt.)

Nhưng vì một lý do nào đó nếu bạn đính kèm cụm từ được chia trong regex trong ngoặc đơn, nó sẽ giữ nguyên trong mảng câu trả lời thay vì chỉ chia nhỏ nó. Tôi không biết nếu đây là một lỗi, một tính năng, hoặc một chút thông minh của thiết kế, tôi không đánh giá cao đúng cách.

Vì vậy, trong thực tế, bạn cần:

s.split(/\s|(==)|(!=)/) 

Nhưng điều này là hầu như không mã mà giải thích riêng của mình. Và cho tất cả tôi biết nó không hoạt động trong 1,9.

1

Something như thế này hoạt động:

s = "12&&32 || 90==12 !=67" 
a = s.split(/ |(\|\|)|(&&)|(!=)|(==)/) 
a.delete("") 
p a 

Đối với một số lý do "" vẫn trong mảng, dòng delete cố định đó.

2

Quy tắc chung của tôi: sử dụng split nếu bạn biết phải vứt bỏ (dấu phân cách), sử dụng regex nếu bạn biết cần giữ gì. Trong trường hợp này bạn biết những gì để giữ cho (các thẻ), vì vậy:

s.scan(/ \w+ | (?: \s|\b)(?: \|\| | && | [=!]=)(?: \s|\b) /x) 
# => ["if", "someBool", "||", "x", "==", "1", "&&", "y", "!=", "22314"] 

Các (?: \s|\b) "delimiters" là để ngăn chặn thẻ của bạn (ví dụ ==) từ phù hợp với một cái gì đó bạn không muốn (ví dụ !==)

+0

Tôi nghĩ rằng quét là c-như và có lẽ hiệu quả hơn và tôi muốn dính vào nó quá – Jose

+1

@ jocapco, nếu "c-like" là quan trọng, tại sao Ruby? –

+0

của nó không quan trọng, nó chỉ goodlooking :) ..ruby bởi vì những gì tôi đang làm đòi hỏi người dùng phải biết rất ít và làm rất nhiều .. sử dụng ngôn ngữ kịch bản như ruby ​​sẽ là thích hợp hơn sau đó. Im vẫn chỉ làm những thứ nhỏ. – Jose

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