Làm cách nào để phân tách một chuỗi có nhiều dấu phân cách trong JavaScript? Tôi đang cố gắng phân tách trên cả dấu phẩy và dấu cách, nhưng, AFAIK, hàm phân tách của JS chỉ hỗ trợ một dấu phân cách.
Làm cách nào để phân tách một chuỗi có nhiều dấu phân cách trong JavaScript? Tôi đang cố gắng phân tách trên cả dấu phẩy và dấu cách, nhưng, AFAIK, hàm phân tách của JS chỉ hỗ trợ một dấu phân cách.
Câu trả lời:
Truyền vào một biểu thức chính quy như tham số:
js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!
Chỉnh sửa để thêm:
Bạn có thể lấy phần tử cuối cùng bằng cách chọn độ dài của mảng trừ 1:
>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"
... và nếu mẫu không khớp:
>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"
(hello world)|\|
đó chưa hoạt động khá. Có ý kiến gì không?
Bạn có thể chuyển regex vào toán tử phân tách của Javascript . Ví dụ:
"1,2 3".split(/,| /)
["1", "2", "3"]
Hoặc, nếu bạn muốn cho phép nhiều dấu phân cách cùng hoạt động như một:
"1, 2, , 3".split(/(?:,| )+/)
["1", "2", "3"]
(Bạn phải sử dụng parens không bắt (? :) vì nếu không, nó sẽ được ghép lại vào kết quả. Hoặc bạn có thể thông minh như Aaron và sử dụng lớp nhân vật.)
(Ví dụ được thử nghiệm trong Safari + FF)
|
như Jesse cho thấy.
Một phương pháp đơn giản nhưng hiệu quả khác là sử dụng split + tham gia nhiều lần.
"a=b,c:d".split('=').join(',').split(':').join(',').split(',')
Về cơ bản, việc phân tách được theo sau bởi một phép nối giống như một sự thay thế toàn cầu, vì vậy điều này thay thế mỗi dấu phân cách bằng dấu phẩy sau đó một khi tất cả được thay thế, nó sẽ phân tách cuối cùng trên dấu phẩy
Kết quả của biểu thức trên là:
['a', 'b', 'c', 'd']
Mở rộng về điều này bạn cũng có thể đặt nó trong một chức năng:
function splitMulti(str, tokens){
var tempChar = tokens[0]; // We can use the first token as a temporary join character
for(var i = 1; i < tokens.length; i++){
str = str.split(tokens[i]).join(tempChar);
}
str = str.split(tempChar);
return str;
}
Sử dụng:
splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]
Nếu bạn sử dụng chức năng này rất nhiều, nó thậm chí có thể đáng để xem xét String.prototype.split
cho thuận tiện (tôi nghĩ rằng chức năng của tôi khá an toàn - sự cân nhắc duy nhất là chi phí bổ sung của các điều kiện (thứ yếu) và thực tế là nó thiếu triển khai đối số giới hạn nếu một mảng được thông qua).
Hãy chắc chắn bao gồm splitMulti
hàm nếu sử dụng phương pháp này dưới đây chỉ đơn giản là kết thúc nó :). Cũng đáng lưu ý rằng một số người cau mày trong việc mở rộng các phần dựng sẵn (vì nhiều người làm sai và có thể xảy ra xung đột), vì vậy nếu nghi ngờ hãy nói với ai đó cao cấp hơn trước khi sử dụng hoặc hỏi trên SO :)
var splitOrig = String.prototype.split; // Maintain a reference to inbuilt fn
String.prototype.split = function (){
if(arguments[0].length > 0){
if(Object.prototype.toString.call(arguments[0]) == "[object Array]" ) { // Check if our separator is an array
return splitMulti(this, arguments[0]); // Call splitMulti
}
}
return splitOrig.apply(this, arguments); // Call original split maintaining context
};
Sử dụng:
var a = "a=b,c:d";
a.split(['=', ',', ':']); // ["a", "b", "c", "d"]
// Test to check that the built-in split still works (although our wrapper wouldn't work if it didn't as it depends on it :P)
a.split('='); // ["a", "b,c:d"]
Thưởng thức!
for(var i = 0; i < tokens.length; i++)
và không for(var i = 1; i < tokens.length; i++)
?
tokens[1]
để lưu một lần lặp tokens[0] == tempchar
và chúng tôi chia ra tempchar
sau khi lặp đi lặp lại tokens
để kết thúc. Tôi sẽ cập nhật câu trả lời phù hợp cảm ơn @tic :).
Hãy giữ cho nó đơn giản: (thêm "[] +" vào RegEx của bạn có nghĩa là "1 hoặc nhiều hơn")
Điều này có nghĩa là "+" và "{1,}" giống nhau.
var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept
Phương pháp khéo léo:
var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]
'('
cho /(/g
đến thay thế tất cả (
các yếu tố - g
là toàn cầu cờ cho RegExp - vì vậy nó tìm kiếm cho tất cả các lần xuất hiện của (
không đầu tiên một
Đối với những người muốn tùy chỉnh nhiều hơn trong chức năng chia tách của họ, tôi đã viết một thuật toán đệ quy phân tách một chuỗi đã cho với một danh sách các ký tự để phân tách. Tôi đã viết điều này trước khi tôi thấy bài viết trên. Tôi hy vọng nó sẽ giúp một số lập trình viên nản lòng.
splitString = function(string, splitters) {
var list = [string];
for(var i=0, len=splitters.length; i<len; i++) {
traverseList(list, splitters[i], 0);
}
return flatten(list);
}
traverseList = function(list, splitter, index) {
if(list[index]) {
if((list.constructor !== String) && (list[index].constructor === String))
(list[index] != list[index].split(splitter)) ? list[index] = list[index].split(splitter) : null;
(list[index].constructor === Array) ? traverseList(list[index], splitter, 0) : null;
(list.constructor === Array) ? traverseList(list, splitter, index+1) : null;
}
}
flatten = function(arr) {
return arr.reduce(function(acc, val) {
return acc.concat(val.constructor === Array ? flatten(val) : val);
},[]);
}
var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
splitString(stringToSplit, splitList);
Ví dụ trên trả về: ["people", "and", "other", "things"]
Lưu ý: flatten
chức năng được lấy từ Rosetta Code
Bạn chỉ có thể gộp tất cả các ký tự bạn muốn sử dụng làm dấu phân cách đơn lẻ hoặc tập thể thành một biểu thức chính quy và chuyển chúng sang hàm phân tách. Chẳng hạn, bạn có thể viết:
console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );
Và đầu ra sẽ là:
["dasdnk", "asd", "naks", ":d", "skldma"]
Xin chào, ví dụ: nếu bạn đã tách và thay thế trong Chuỗi 07:05:45 PM
var hour = time.replace("PM", "").split(":");
Kết quả
[ '07', '05', '45' ]
Đây là một cách mới để đạt được điều tương tự trong ES6 :
function SplitByString(source, splitBy) {
var splitter = splitBy.split('');
splitter.push([source]); //Push initial value
return splitter.reduceRight(function(accumulator, curValue) {
var k = [];
accumulator.forEach(v => k = [...k, ...v.split(curValue)]);
return k;
});
}
var source = "abc,def#hijk*lmn,opq#rst*uvw,xyz";
var splitBy = ",*#";
console.log(SplitByString(source, splitBy));
Xin lưu ý trong chức năng này:
source
Kết quả của mã trên sẽ là:
Phản hồi của tôi về câu trả lời @Brian
var string = 'and this is some kind of information and another text and simple and some egample or red or text';
var separators = ['and', 'or'];
function splitMulti(str, separators){
var tempChar = 't3mp'; //prevent short text separator in split down
//split by regex e.g. \b(or|and)\b
var re = new RegExp('\\b(' + separators.join('|') + ')\\b' , "g");
str = str.replace(re, tempChar).split(tempChar);
// trim & remove empty
return str.map(el => el.trim()).filter(el => el.length > 0);
}
console.log(splitMulti(string, separators))
Tôi thấy rằng một trong những lý do chính tôi cần điều này là để phân chia đường dẫn tệp trên cả hai /
và \
. Đó là một chút của một regex phức tạp vì vậy tôi sẽ đăng nó ở đây để tham khảo:
var splitFilePath = filePath.split(/[\/\\]/);
Tôi nghĩ sẽ dễ dàng hơn nếu bạn chỉ định những gì bạn muốn để lại, thay vì những gì bạn muốn loại bỏ.
Như thể bạn chỉ muốn có các từ tiếng Anh, bạn có thể sử dụng một cái gì đó như thế này:
text.match(/[a-z'\-]+/gi);
Ví dụ (chạy đoạn trích):
var R=[/[a-z'\-]+/gi,/[a-z'\-\s]+/gi];
var s=document.getElementById('s');
for(var i=0;i<R.length;i++)
{
var o=document.createElement('option');
o.innerText=R[i]+'';
o.value=i;
s.appendChild(o);
}
var t=document.getElementById('t');
var r=document.getElementById('r');
s.onchange=function()
{
r.innerHTML='';
var x=s.value;
if((x>=0)&&(x<R.length))
x=t.value.match(R[x]);
for(i=0;i<x.length;i++)
{
var li=document.createElement('li');
li.innerText=x[i];
r.appendChild(li);
}
}
<textarea id="t" style="width:70%;height:12em">even, test; spider-man
But saying o'er what I have said before:
My child is yet a stranger in the world;
She hath not seen the change of fourteen years,
Let two more summers wither in their pride,
Ere we may think her ripe to be a bride.
—Shakespeare, William. The Tragedy of Romeo and Juliet</textarea>
<p><select id="s">
<option selected>Select a regular expression</option>
<!-- option value="1">/[a-z'\-]+/gi</option>
<option value="2">/[a-z'\-\s]+/gi</option -->
</select></p>
<ol id="r" style="display:block;width:auto;border:1px inner;overflow:scroll;height:8em;max-height:10em;"></ol>
</div>
Bắt đầu từ giải pháp @ stephen-sweriduk (điều đó thú vị hơn với tôi!), Tôi đã sửa đổi một chút để làm cho chung chung hơn và có thể sử dụng lại:
/**
* Adapted from: http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript
*/
var StringUtils = {
/**
* Flatten a list of strings
* http://rosettacode.org/wiki/Flatten_a_list
*/
flatten : function(arr) {
var self=this;
return arr.reduce(function(acc, val) {
return acc.concat(val.constructor === Array ? self.flatten(val) : val);
},[]);
},
/**
* Recursively Traverse a list and apply a function to each item
* @param list array
* @param expression Expression to use in func
* @param func function of (item,expression) to apply expression to item
*
*/
traverseListFunc : function(list, expression, index, func) {
var self=this;
if(list[index]) {
if((list.constructor !== String) && (list[index].constructor === String))
(list[index] != func(list[index], expression)) ? list[index] = func(list[index], expression) : null;
(list[index].constructor === Array) ? self.traverseListFunc(list[index], expression, 0, func) : null;
(list.constructor === Array) ? self.traverseListFunc(list, expression, index+1, func) : null;
}
},
/**
* Recursively map function to string
* @param string
* @param expression Expression to apply to func
* @param function of (item, expressions[i])
*/
mapFuncToString : function(string, expressions, func) {
var self=this;
var list = [string];
for(var i=0, len=expressions.length; i<len; i++) {
self.traverseListFunc(list, expressions[i], 0, func);
}
return self.flatten(list);
},
/**
* Split a string
* @param splitters Array of characters to apply the split
*/
splitString : function(string, splitters) {
return this.mapFuncToString(string, splitters, function(item, expression) {
return item.split(expression);
})
},
}
và sau đó
var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);
trả lại như ban đầu:
[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]
Một cách dễ dàng để làm điều này là xử lý từng ký tự của chuỗi với mỗi dấu phân cách và xây dựng một mảng của các phần tách:
splix = function ()
{
u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0;
for (i = 0; i < u.length; ++i)
{
for (j = 0; j < v.length; ++j)
{
if (u.slice(i, i + v[j].length) == v[j])
{
y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1];
};
};
};
return w;
};
Sử dụng:
splix(string, delimiters...)
Thí dụ:
splix("1.23--4", ".", "--")
Trả về:
["1", "23", "4"]
Tôi sẽ cung cấp một triển khai cổ điển cho một chức năng như vậy. Mã này hoạt động trong hầu hết tất cả các phiên bản JavaScript và bằng cách nào đó là tối ưu.
Chỉ cần mã thuần túy:
var text = "Create a function, that will return an array (of string), with the words inside the text";
println(getWords(text));
function getWords(text)
{
let startWord = -1;
let ar = [];
for(let i = 0; i <= text.length; i++)
{
let c = i < text.length ? text[i] : " ";
if (!isSeparator(c) && startWord < 0)
{
startWord = i;
}
if (isSeparator(c) && startWord >= 0)
{
let word = text.substring(startWord, i);
ar.push(word);
startWord = -1;
}
}
return ar;
}
function isSeparator(c)
{
var separators = [" ", "\t", "\n", "\r", ",", ";", ".", "!", "?", "(", ")"];
return separators.includes(c);
}
Bạn có thể thấy mã đang chạy trong sân chơi: https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf
Tôi không biết hiệu năng của RegEx, nhưng đây là một giải pháp thay thế khác cho RegEx tận dụng Hashset gốc và hoạt động ở độ phức tạp O (max (str.length, delimet.length)):
var multiSplit = function(str,delimiter){
if (!(delimiter instanceof Array))
return str.split(delimiter);
if (!delimiter || delimiter.length == 0)
return [str];
var hashSet = new Set(delimiter);
if (hashSet.has(""))
return str.split("");
var lastIndex = 0;
var result = [];
for(var i = 0;i<str.length;i++){
if (hashSet.has(str[i])){
result.push(str.substring(lastIndex,i));
lastIndex = i+1;
}
}
result.push(str.substring(lastIndex));
return result;
}
multiSplit('1,2,3.4.5.6 7 8 9',[',','.',' ']);
// Output: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
multiSplit('1,2,3.4.5.6 7 8 9',' ');
// Output: ["1,2,3.4.5.6", "7", "8", "9"]
Không phải là cách tốt nhất nhưng hoạt động để phân chia với nhiều phân tách / phân cách khác nhau
html
<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>
javascript
<script>
function myFunction() {
var str = "How : are | you doing : today?";
var res = str.split(' | ');
var str2 = '';
var i;
for (i = 0; i < res.length; i++) {
str2 += res[i];
if (i != res.length-1) {
str2 += ",";
}
}
var res2 = str2.split(' : ');
//you can add countless options (with or without space)
document.getElementById("demo").innerHTML = res2;
</script>
Tôi sử dụng regrec:
str = 'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';
var strNew = str.match(/\w+/g);
// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]