Chia chuỗi trên lần xuất hiện khoảng trắng đầu tiên


149

Tôi đã không nhận được một biểu thức chính được tối ưu hóa để chia cho tôi một Chuỗi dựa trên sự xuất hiện của khoảng trắng đầu tiên:

var str="72 tocirah sneab";

Tôi cần lấy:

[
    "72",
    "tocirah sneab",
]

1
"Tối ưu hóa" nghĩa là gì? Nó phải là một regex không?
Deestan

Vui lòng dành thời gian để cuộn xuống câu trả lời của @ georg - stackoverflow
Sanjay Manohar

Câu trả lời:


323

Nếu bạn chỉ quan tâm đến ký tự khoảng trắng (chứ không phải các tab hoặc các ký tự khoảng trắng khác) và chỉ quan tâm đến mọi thứ trước khoảng trắng đầu tiên và mọi thứ sau khoảng trắng đầu tiên, bạn có thể thực hiện nó mà không cần biểu thức chính quy như sau:

str.substr(0,str.indexOf(' ')); // "72"
str.substr(str.indexOf(' ')+1); // "tocirah sneab"

Lưu ý rằng nếu không có khoảng trống nào, thì dòng đầu tiên sẽ trả về một chuỗi trống và dòng thứ hai sẽ trả về toàn bộ chuỗi. Hãy chắc chắn rằng đó là hành vi mà bạn muốn trong tình huống đó (hoặc tình huống đó sẽ không phát sinh).


49

Javascript không hỗ trợ lookbehinds, vì vậy splitkhông thể. matchlàm:

str.match(/^(\S+)\s(.*)/).slice(1)

Một mẹo khác:

str.replace(/\s+/, '\x01').split('\x01')

làm thế nào về:

[str.replace(/\s.*/, ''), str.replace(/\S+\s/, '')]

và tại sao không

reverse = function (s) { return s.split('').reverse().join('') }
reverse(str).split(/\s(?=\S+$)/).reverse().map(reverse)

hoặc có thể

re = /^\S+\s|.*/g;
[].concat.call(re.exec(str), re.exec(str))

Cập nhật 2019 : kể từ ES2018, lookbehinds được hỗ trợ:

str = "72 tocirah sneab"
s = str.split(/(?<=^\S+)\s/)
console.log(s)


str.match(/^(\S+)\s(.*)/).slice(1) sẽ không làm việc cho một chuỗi không có khoảng trống
Junaid

29

Trong ES6 bạn cũng có thể

let [first, ...second] = str.split(" ")
second = second.join(" ")

2
Tôi thích điều này khá nhiều và nó hoạt động tốt nhưng hiệu suất khôn ngoan, nó khá tệ với giải pháp "chuỗi con" được nâng cấp nhất. chỉ cần thử nghiệm và nó chậm hơn khoảng 10 lần.
pootzko

18

Cuối trò chơi, tôi biết nhưng dường như có một cách rất đơn giản để làm điều này:

const str = "72 tocirah sneab";
const arr = str.split(/ (.*)/);
console.log(arr);

Điều này sẽ để lại arr[0]với "72"arr[1]với "tocirah sneab". Lưu ý rằng mảng [2] sẽ trống, nhưng bạn có thể bỏ qua nó.

Để tham khảo:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split#Capturing_parentheses


Lưu ý rằng điều này tạo ra một yếu tố trống cuối cùng.
Benjamin Intal

13
var arr = [];             //new storage
str = str.split(' ');     //split by spaces
arr.push(str.shift());    //add the number
arr.push(str.join(' '));  //and the rest of the string

//arr is now:
["72","tocirah sneab"];

nhưng tôi vẫn nghĩ rằng có một cách nhanh hơn mặc dù.


11

Giải pháp của georg là tốt, nhưng sẽ phá vỡ nếu chuỗi không chứa bất kỳ khoảng trắng nào. Nếu chuỗi của bạn có cơ hội không chứa khoảng trắng, sử dụng .split và chụp các nhóm như vậy sẽ an toàn hơn:

str_1 = str.split(/\s(.+)/)[0];  //everything before the first space
str_2 = str.split(/\s(.+)/)[1];  //everything after the first space

9

Bạn cũng có thể sử dụng .replace để chỉ thay thế lần xuất hiện đầu tiên,

str = str.replace(' ','<br />');

Rời khỏi / g.

BẢN GIỚI THIỆU


3
@DannyHerran .. Không, nó sẽ không? Bạn thậm chí đã kiểm tra mã? Không có sửa đổi / g. Nó không phải là toàn cầu. Hãy thử kiểm tra mã trước khi bạn có ý định biết nó làm gì . Đã thử nghiệm trong ba trình duyệt chính. Tôi muốn biết lý do tại sao bạn nghĩ những gì bạn làm.
Daedalus

Điều đó thông minh bởi vì tôi luôn coi đây là một khuyết điểm. Đây là lần đầu tiên tôi thấy điều này bị lợi dụng :)
Gogol

2

Chỉ cần chia chuỗi thành một mảng và dán các phần bạn cần lại với nhau. Cách tiếp cận này rất linh hoạt, nó hoạt động trong nhiều tình huống và rất dễ để lý do. Thêm vào đó bạn chỉ cần một chức năng gọi.

arr = str.split(' ');             // ["72", "tocirah", "sneab"]
strA = arr[0];                    // "72"
strB = arr[1] + ' ' + arr[2];     // "tocirah sneab"

Ngoài ra, nếu bạn muốn chọn những thứ bạn cần trực tiếp từ chuỗi, bạn có thể làm một cái gì đó như thế này:

strA = str.split(' ')[0];                    // "72";
strB = str.slice(strA.length + 1);           // "tocirah sneab"

Hoặc như thế này:

strA = str.split(' ')[0];                    // "72";
strB = str.split(' ').splice(1).join(' ');   // "tocirah sneab"

Tuy nhiên tôi đề nghị ví dụ đầu tiên.

Bản demo làm việc: jsbin


Như thế này! Có "khuyết điểm"?
iglesiasedd

0

Bất cứ khi nào tôi cần lấy một lớp từ danh sách các lớp hoặc một phần của tên lớp hoặc id, tôi luôn sử dụng split () sau đó lấy nó cụ thể với chỉ mục mảng hoặc, thường là trong trường hợp của tôi, pop () để lấy phần tử cuối cùng hoặc shift () để lấy phần tử đầu tiên.

Ví dụ này lấy các lớp của div "gallery_148 ui-sortable" và trả về id thư viện 148.

var galleryClass = $(this).parent().prop("class"); // = gallery_148 ui-sortable
var galleryID = galleryClass.split(" ").shift(); // = gallery_148
galleryID = galleryID.split("_").pop(); // = 148
//or
galleryID = galleryID.substring(8); // = 148 also, but less versatile 

Tôi chắc chắn rằng nó có thể được nén thành ít dòng hơn nhưng tôi đã mở rộng nó để dễ đọc.


0

Tôi cần một kết quả hơi khác.

Tôi muốn từ đầu tiên, và những gì đã đến sau nó - ngay cả khi nó trống.

str.substr(0, text.indexOf(' ') == -1 ? text.length : text.indexOf(' '));
str.substr(text.indexOf(' ') == -1 ? text.length : text.indexOf(' ') + 1);

Vì vậy, nếu đầu vào là onewordbạn nhận được oneword''.

Nếu đầu vào là one word and some morebạn nhận được oneword and some more.


0

Tôi không chắc tại sao tất cả các câu trả lời khác rất phức tạp, khi bạn có thể thực hiện tất cả trong một dòng, xử lý việc thiếu không gian.

Ví dụ: hãy lấy các thành phần đầu tiên và "khác" của tên:

let [first, last] = 'John Von Doe'.split(/ (.*)/);
console.log({ first, last });

[first, last] = 'Surma'.split(/ (.*)/);
console.log({ first, last });


-1

Hàm sau sẽ luôn chia câu thành 2 phần tử. Phần tử đầu tiên sẽ chỉ chứa từ đầu tiên và phần tử thứ hai sẽ chứa tất cả các từ khác (hoặc nó sẽ là một chuỗi trống).

var arr1 = split_on_first_word("72 tocirah sneab");       // Result: ["72", "tocirah sneab"]
var arr2 = split_on_first_word("  72  tocirah sneab  ");  // Result: ["72", "tocirah sneab"]
var arr3 = split_on_first_word("72");                     // Result: ["72", ""]
var arr4 = split_on_first_word("");                       // Result: ["", ""]

function split_on_first_word(str)
{
    str = str.trim();  // Clean string by removing beginning and ending spaces.

    var arr = [];
    var pos = str.indexOf(' ');  // Find position of first space

    if ( pos === -1 ) {
        // No space found
        arr.push(str);                // First word (or empty)
        arr.push('');                 // Empty (no next words)
    } else {
        // Split on first space
        arr.push(str.substr(0,pos));         // First word
        arr.push(str.substr(pos+1).trim());  // Next words
    }

    return arr;
}

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.