Chia chuỗi một lần trong javascript?


81

Làm cách nào để tôi có thể tách một chuỗi chỉ một lần, tức là thực hiện 1|Ceci n'est pas une pipe: | Ouiphân tích cú pháp thành:["1", "Ceci n'est pas une pipe: | Oui"] :?

Giới hạn phân chia dường như không giúp ích được gì ...

Câu trả lời:


77

Đây không phải là một cách tiếp cận đẹp, nhưng hoạt động với hiệu quả khá:

var string = "1|Ceci n'est pas une pipe: | Oui";
var components = string.split('|');
alert([components.shift(), components.join('|')]​);​​​​​

Đây là bản demo nhanh về nó


Tôi nghĩ điều này thực sự tốt hơn regex. Đã chọn đúng, cảm ơn!
Stavros Korokithakis

2
Để làm rõ, anh ấy chia thành N phần sau đó đưa phần đầu tiên vào danh sách và nối phần còn lại vào cùng một danh sách.
Stavros Korokithakis

Nếu bạn muốn lấy k mã thông báo ra khỏi chuỗi thay vì 1, hãy thực hiện tương tự như trên ngoại trừ sử dụng component.splice (0, k) thay vì components.shift ().
D Coetzee

Đối với những người tự hỏi làm thế nào để làm điều này với 2 hoặc nhiều hơn các ngăn, Bạn có thể sử dụng sự thay đổi trong một vòng lặp hoặc:components.splice(0,2).slice(0,2)
ultimater

113

Bạn muốn sử dụng String.indexOf('|')để lấy chỉ mục của lần xuất hiện đầu tiên của '|'.

var i = s.indexOf('|');
var splits = [s.slice(0,i), s.slice(i+1)];

17
Không "vui vẻ" như của Nick, nhưng có lẽ hiệu quả hơn. Cũng lưu ý rằng +1thực sự phải là độ dài của chuỗi phân tách, nếu có nhiều hơn một ký tự.
defos1

Tại sao giải pháp này kém "vui" hơn?
Bentley

Đối với những người tự hỏi, để làm điều này với 2 hoặc nhiều hơn các khối, bạn có thể sử dụng indexOf trong một vòng lặp hoặc:var i = s.split('|',2).join('|').length;//2nd index var splits = [s.slice(0,i).split('|'), s.slice(i+1)];
ultimater

6
Điều này KHÔNG hoạt động giống như phân tách khi IndexOf trả về -1 (Ví dụ: nếu var s = 'string' nó sẽ trả về ['strin', 'string']). Bạn sẽ phải viết một điều kiện.
JJJ

14

Bạn có thể dùng:

var splits = str.match(/([^|]*)\|(.*)/);
splits.shift();

Regex chia chuỗi thành hai nhóm phù hợp (được đặt trong ngoặc đơn), văn bản đứng trước | và văn bản sau. Sau đó, chúng tôi shiftkết quả để loại bỏ toàn bộ chuỗi khớp ( splits[0]).


1
đúng cách, điều đó có thể sẽ neo ngay từ đầu. tuy nhiên javascript regexen có vẻ tham lam.
muhmuhten

6

một lớp lót và imo, đơn giản hơn:

var str = 'I | am super | cool | yea!';
str.split('|').slice(1).join('|');

Điều này trả về "am super | cool | yea!"


3
Đây không phải là thứ được yêu cầu, họ cũng đang tìm kiếm phần đầu tiên còn thiếu.
SmujMaiku

5

Cú pháp ES6 cho phép một cách tiếp cận khác:

function splitOnce(s, on) {
   [first, ...rest] = s.split(on)
   return [first, rest.length > 0? rest.join(on) : null]
}

Điều này cũng xử lý trường hợp chuỗi không có a |bằng cách trả về null thay vì chuỗi rỗng, điều này rõ ràng hơn.

splitOnce("1|Ceci n'est pas une pipe: | Oui", "|")
>>> ["1", "Ceci n'est pas une pipe: | Oui"]

splitOnce("Celui-ci n'a pas de pipe symbol!", "|")
>>> ["Celui-ci n'a pas de pipe symbol!", null]

Pas de tẩu? C'est null!

Tôi đã thêm câu trả lời này chủ yếu để tôi có thể chơi chữ ký hiệu ống dẫn, nhưng cũng để thể hiện cú pháp es6 - thật tuyệt vời khi nhiều người vẫn không sử dụng nó ...


3

Thử đi:

function splitOnce(input, splitBy) {
    var fullSplit = input.split(splitBy);
    var retVal = [];
    retVal.push( fullSplit.shift() );
    retVal.push( fullSplit.join( splitBy ) );
    return retVal;
}

var whatever = splitOnce("1|Ceci n'est pas une pipe: | Oui", '|');

3

Nếu chuỗi không chứa dấu phân tách @ thì giải pháp của NickCraver sẽ vẫn trả về một mảng gồm hai phần tử, phần tử thứ hai là một chuỗi trống. Tôi thích hành vi phù hợp với hành vi chia tách. Nghĩa là, nếu chuỗi đầu vào không chứa dấu phân cách thì chỉ trả về một mảng với một phần tử duy nhất.

var splitOnce = function(str, delim) {
    var components = str.split(delim);
    var result = [components.shift()];
    if(components.length) {
        result.push(components.join(delim));
    }
    return result;
};

splitOnce("a b c d", " "); // ["a", "b c d"]
splitOnce("a", " "); // ["a"]

1

Cũng ác như hầu hết các câu trả lời cho đến nay:

var splits = str.split('|');
splits.splice(1, splits.length - 1, splits.slice(1).join('|'));

0

Một cách tiếp cận ngắn, thay thế, bên cạnh những hàng hóa ở nơi khác, là sử dụng replace()giới hạn để có lợi cho bạn.

var str = "1|Ceci n'est pas une pipe: | Oui";
str.replace("|", "aUniquePhraseToSaySplitMe").split("aUniquePhraseToSaySplitMe");

Như @sreservoir đã chỉ ra trong các nhận xét, cụm từ duy nhất phải thực sự độc đáo - nó không thể nằm trong nguồn mà bạn đang chạy phần tách này, hoặc bạn sẽ nhận được chuỗi bị chia thành nhiều phần hơn bạn muốn. Một ký tự không thể in được, như anh ấy nói, có thể xảy ra nếu bạn đang chạy điều này dựa trên đầu vào của người dùng (tức là được nhập trong trình duyệt).


điều đó chỉ hoạt động nếu cụm từ 'duy nhất' là không thể nhập. nếu đọc từ một tệp văn bản, điều này là không thể. nếu đọc từ trình duyệt, bất kỳ ký tự điều khiển không in được nếu có thể tốt. tab cũng hoạt động kỳ diệu. trong mọi trường hợp, "aUniquePhraseToSaySplitMe" gần như chắc chắn có thể là một phần của đầu vào và do đó nguy hiểm.
muhmuhten

Tất nhiên là bạn đúng. Ví dụ của tôi chỉ là một ví dụ nhằm giải thích những gì đang được thực hiện một cách ngắn gọn. Tôi sẽ kết hợp quan điểm của bạn vào chính câu trả lời. Cảm ơn!

Nếu bạn sử dụng str cho cụm từ duy nhất của mình, bạn biết nó không thể có trong đó một lần nữa! : grin ác
Fabio Beltramini

0

Điều này dài hơn một chút, nhưng nó hoạt động như tôi tin rằng giới hạn nên:

function split_limit(inString, separator, limit){
    var ary = inString.split(separator);
    var aryOut = ary.slice(0, limit - 1);
    if(ary[limit - 1]){
        aryOut.push(ary.slice(limit - 1).join(separator));
    }
    return aryOut;
}
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 1));
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 2));
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 3));
console.log(split_limit("1|Ceci n'est pas une pipe: | Oui","|", 7));

https://jsfiddle.net/2gyxuo2j/

giới hạn của Zero trả về kết quả hài hước, nhưng vì hiệu quả, tôi đã bỏ qua việc kiểm tra nó. Bạn có thể thêm điều này làm dòng đầu tiên của hàm nếu bạn cần:

if(limit < 1) return [];

0

nếu bạn muốn sử dụng "đường ống", reducebạn của bạn

const separator = '|'
jsonNode.split(separator)
   .reduce((previous, current, index) =>
    {
        if (index < 2) previous.push(current)
        else previous[1] += `${separator}${current}`
        return previous
    }, [])
    .map((item: string) => (item.trim()))
    .filter((item: string) => (item != ''))

0

Phương pháp hiệu quả hơn:

const str = "1|Ceci n'est pas une pipe: | Oui"

const [head] = str.split('|', 1);

const result = [head, str.substr(head.length + 1)]

console.log(result);


-1

sử dụng chức năng biểu thức chính quy javascript và lấy biểu thức được ghi lại đầu tiên.

RE có thể sẽ trông như thế nào /^([^|]*)\|/.

trên thực tế, bạn chỉ cần /[^|]*/nếu bạn xác thực rằng chuỗi được định dạng theo cách như vậy, do tính tham lam regex của javascript.

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.