2011-09-16 26 views
9

Với chuỗi này:regex - trả lại tất cả trước khi sự xuất hiện thứ hai

DNS000001320_309.0/121.0_t0 

Làm thế nào tôi sẽ trở lại tất cả mọi thứ trước khi sự xuất hiện thứ hai của "_"?

DNS000001320_309.0/121.0 

Tôi đang sử dụng R.

Cảm ơn.

+0

Bất kỳ sự đảm bảo rằng các dây sẽ luôn luôn có một giây _ ? Làm thế nào để bạn muốn xử lý các trường hợp có 0 hoặc 1 dấu gạch dưới? – Brian

+0

Nó sẽ luôn luôn có 2 "_" s ... đảm bảo! Chuỗi là một 'dán' của 3 chuỗi sử dụng' sep = "_" '. – James

Trả lời

9

Tôi nghĩ rằng điều này có thể làm nhiệm vụ (regex để phù hợp với tất cả mọi thứ befor sự xuất hiện cuối cùng của _):

_([^_]*)$ 

Ví dụ:

> sub('_([^_]*)$', '', "DNS000001320_309.0/121.0_t0") 
[1] "DNS000001320_309.0/121.0" 
+0

Vâng, nếu đường dẫn regex được đi, 'sub' sẽ phù hợp hơn' gsub'. –

+2

Nếu có nhiều hơn hai dấu gạch dưới, điều này sẽ chọn ngoài dấu gạch dưới thứ hai, mặc dù dường như không quan trọng đối với OP, vì vậy tôi chỉ chỉ ra cho hậu thế. – joran

+0

Vâng, điểm tốt @joran. Nó có thể quan trọng với OP, nhưng anh ta có thể không nhận thức được nó. –

11

Cá nhân, tôi ghét regex, vì vậy may mắn có một cách để làm điều này mà không có họ, chỉ bằng cách tách chuỗi:

> s <- "DNS000001320_309.0/121.0_t0"  
> paste(strsplit(s,"_")[[1]][1:2],collapse = "_") 
[1] "DNS000001320_309.0/121.0" 

Mặc dù tất nhiên điều này giả định rằng sẽ luôn có ít nhất 2 dấu gạch dưới trong của bạn chuỗi, vì vậy hãy cẩn thận nếu bạn vectorize này và đó không phải là trường hợp.

+0

đánh bại tôi bằng 12 giây: p – darckeen

+0

@darckeen Những ý tưởng tuyệt vời .... như họ nói. ;) – joran

+0

+1 cho 'strplit' - cách tôi giải quyết vấn đề này trong R. – daroczig

6

không đẹp nhưng điều này sẽ làm các trick

mystr <- "DNS000001320_309.0/121.0_t0" 

mytok <- paste(strsplit(mystr,"_")[[1]][1:2],collapse="_") 
36

Các kịch bản sau đây:

s <- "DNS000001320_309.0/121.0_t0" 
t <- gsub("^([^_]*_[^_]*)_.*$", "\\1", s) 
t 

sẽ in:

DNS000001320_309.0/121.0 

Một lời giải thích nhanh chóng của các regex:

^   # the start of the input 
(  # start group 1 
    [^_]* # zero or more chars other than `_` 
    _  # a literal `_` 
    [^_]* # zero or more chars other than `_` 
)   # end group 1 
_   # a literal `_` 
.*  # consume the rest of the string 
$   # the end of the input 

mà được thay thế bằng:

\\1  # whatever is matched in group 1 

Và nếu có ít hơn 2 dấu gạch dưới, chuỗi là không thay đổi.

+0

Câu trả lời thật, hay, chi tiết (+1). Tôi chắc chắn như giải pháp của bạn tốt hơn tôi :) – daroczig

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