2015-06-03 21 views
12

Giả sử tôi có một chuỗi: "We.need..to...split.asap". Những gì tôi muốn làm là chia chuỗi theo dấu phân cách ., nhưng tôi chỉ muốn chia cho trước tiên. và bao gồm bất kỳ định kỳ . s trong mã thông báo thành công.Cách tách chuỗi bằng ký tự không phải trước ký tự cùng loại?

mong đợi đầu ra:

["We", "need", ".to", "..split", "asap"] 

Trong các ngôn ngữ khác, tôi biết rằng điều này là có thể với một cái nhìn phía sau /(?<!\.)\./ nhưng Javascript tiếc là không hỗ trợ một tính năng như vậy.

Tôi rất tò mò muốn xem câu trả lời của bạn cho câu hỏi này. Có lẽ có một cách sử dụng thông minh của cái nhìn-ah hiện nay evades tôi?

Tôi đã xem xét đảo ngược chuỗi, sau đó lại đảo ngược các thẻ, nhưng điều đó dường như làm việc quá nhiều cho những gì tôi sau ... cộng với tranh cãi: How do you reverse a string in place in JavaScript?

Thanks for the help!

+1

'" We.need..to ... split.asap ".split (/ \ b \ ./)', nhưng điều này chỉ hoạt động nếu '.' đầu tiên được bắt đầu bằng ký tự từ. – nhahtdh

Trả lời

5

Dưới đây là một biến thể của the answer by guest271314 để xử lý hơn hai delimiters liên tiếp:

var text = "We.need.to...split.asap"; 
var re = /(\.*[^.]+)\./; 
var items = text.split(re).filter(function(val) { return val.length > 0; }); 

Nó sử dụng các chi tiết rằng nếu biểu thức chia bao gồm một nhóm chụp, các mục đã chụp được bao gồm trong mảng được trả về. Các nhóm chụp này thực sự là điều duy nhất chúng tôi quan tâm; các mã thông báo là tất cả các chuỗi trống, chúng tôi lọc ra.

EDIT: Thật không may có lẽ có một lỗi nhỏ với điều này. Nếu văn bản được tách ra bắt đầu bằng dấu phân cách, văn bản đó sẽ được bao gồm trong mã thông báo đầu tiên. Nếu đó là một vấn đề, nó có thể được khắc phục với:

var re = /(?:^|(\.*[^.]+))\./; 
var items = text.split(re).filter(function(val) { return !!val; }); 

(Tôi nghĩ rằng regex này là xấu xí và sẽ chào đón một sự cải tiến.)

2

Lưu ý: Câu trả lời này không thể xử lý nhiều hơn 2 dấu phân cách liên tiếp, vì nó được viết theo ví dụ trong the revision 1 of the question, điều này không rõ ràng về các trường hợp như vậy.


var text = "We.need.to..split.asap"; 
 
// split "." if followed by "." 
 
var res = text.split(/\.(?=\.)/).map(function(val, key) { 
 
    // if `val[0]` does not begin with "." split "." 
 
    // else split "." if not followed by "." 
 
    return val[0] !== "." ? val.split(/\./) : val.split(/\.(?!.*\.)/) 
 
}); 
 
// concat arrays `res[0]` , `res[1]` 
 
res = res[0].concat(res[1]); 
 

 
document.write(JSON.stringify(res));

+0

Đó là thông minh, nhưng không thể xử lý bất kỳ hơn 2 dấu phân cách liên tiếp. ví dụ: "we.need.to ... split.asap". Tuy nhiên, tôi sẽ bỏ phiếu vì điều đó không rõ ràng trong ví dụ của câu hỏi. – DRAB

+3

@DRAB Có lẽ bao gồm _ "xử lý bất kỳ hơn hai dấu phân tách liên tiếp. Ví dụ:" we.need.to ... split.asap "" _ "vì không rõ ràng cụ thể trong ví dụ của câu hỏi." _ At Question? – guest271314

+3

Nhiều hơn hai dấu phân tách được ngụ ý bằng cách sử dụng số nhiều của OP: "bất kỳ định kỳ'. 'S". –

3

Bạn có thể làm điều này mà không cần bất kỳ lookaheads:

var subject = "We.need.to....split.asap"; 
 
var regex = /\.?(\.*[^.]+)/g; 
 

 
var matches, output = []; 
 

 
while(matches = regex.exec(subject)) { 
 
    output.push(matches[1]); 
 
} 
 

 
document.write(JSON.stringify(output));

Dường như nó hoạt động trong một dòng, giống như trên https://regex101.com/r/cO1dP3/1, nhưng phải được mở rộng trong mã ở trên vì tùy chọn /g theo mặc định sẽ ngăn các nhóm quay trở lại với .match (tức là dữ liệu chính xác nằm trong nhóm chụp, nhưng chúng tôi không thể truy cập chúng ngay lập tức mà không làm như trên).

Xem: JavaScript Regex Global Match Groups

Một giải pháp thay thế với bản gốc lót (cộng với một dòng) là:

document.write(JSON.stringify(
 
    "We.need.to....split.asap".match(/\.?(\.*[^.]+)/g) 
 
     .map(function(s) { return s.replace(/^\./, ''); }) 
 
));

Hãy chọn của bạn!

+0

Đây không phải là những gì OP muốn, bao gồm ** tất cả trừ một dấu phân cách trước đó trong mỗi mã thông báo. (Nói cách khác, kết quả sẽ là '[" Chúng tôi "," cần "," thành "," ... tách "," càng sớm càng "]'. –

+0

Tôi biết, đã xảy ra sự cố khi di chuyển regex từ regex101 .com đến đây. Hiện tại, bạn nên làm việc, nhưng không còn 1 dòng nữa: ( –

+0

Tốt hơn nhiều. +1 –

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