JavaScript'te birden çok ayırıcılı bir dizeyi nasıl bölerim? Hem virgül hem de boşluk üzerinde bölmeye çalışıyorum ama AFAIK, JS bölünme işlevi sadece bir ayırıcı destekler.
JavaScript'te birden çok ayırıcılı bir dizeyi nasıl bölerim? Hem virgül hem de boşluk üzerinde bölmeye çalışıyorum ama AFAIK, JS bölünme işlevi sadece bir ayırıcı destekler.
Yanıtlar:
Parametre olarak bir normal ifade girin:
js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!
Eklemek için düzenlendi:
Eksi 1 dizisinin uzunluğunu seçerek son elemanı alabilirsiniz:
>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"
... ve desen eşleşmiyorsa:
>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"
(hello world)|\|
henüz işe yaramadı. Herhangi bir fikir?
Bir regex'i Javascript'in split işlecine geçirebilirsiniz . Örneğin:
"1,2 3".split(/,| /)
["1", "2", "3"]
Veya, birden çok ayırıcının birlikte yalnızca tek bir işlev görmesine izin vermek istiyorsanız:
"1, 2, , 3".split(/(?:,| )+/)
["1", "2", "3"]
(Yakalamayan (? :) ebeveynleri kullanmalısınız çünkü aksi takdirde sonuca geri eklenir. Veya Aaron gibi akıllı olabilir ve bir karakter sınıfı kullanabilirsiniz.)
(Safari + FF'de test edilen örnekler)
|
Jesse'nin gösterdiği gibi ayırın .
Bir başka basit ama etkili yöntem split + join'i tekrar tekrar kullanmaktır.
"a=b,c:d".split('=').join(',').split(':').join(',').split(',')
Temelde bir ayrılma ve ardından bir birleşim yapmak küresel bir değiştirme gibidir, bu yüzden bu her ayırıcıyı bir virgülle değiştirir, sonra hepsi değiştirildikten sonra virgül üzerinde son bir bölünme yapar
Yukarıdaki ifadenin sonucu:
['a', 'b', 'c', 'd']
Bunu genişleterek bir işleve de yerleştirebilirsiniz:
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;
}
Kullanımı:
splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]
Bu işlevselliği çok kullanırsanız String.prototype.split
, rahatlık için kaydırmayı düşünmeye bile değer olabilir (işlevimin oldukça güvenli olduğunu düşünüyorum - tek düşünce, koşulların (küçük) ek yükü ve sınır bağımsız değişkeninin uygulanmasından yoksun olmasıdır. bir dizi geçirilirse).
splitMulti
Aşağıya doğru bu yaklaşımı kullanırsanız , işlevi eklediğinizden emin olun :). Ayrıca, bazı insanların yerleşikleri genişletme konusunda kaşlarını çattığına dikkat edin (birçok insan yanlış yapar ve çatışmalar meydana gelebilir), bu yüzden şüpheniz varsa bunu kullanmadan önce daha üst düzey biriyle konuşun veya SO'ya sorun :)
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
};
Kullanımı:
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"]
Zevk almak!
for(var i = 0; i < tokens.length; i++)
değil for(var i = 1; i < tokens.length; i++)
?
tokens[1]
olarak bir yineleme kaydetmek tokens[0] == tempchar
ve biz bölünmüş tempchar
yineleme sonra tokens
bitirmek için. Cevabı buna göre güncelleyeceğim teşekkürler @tic :).
Basit tutalım: (RegEx'inize "1 veya daha fazla" anlamına gelen bir "[] +" ekleyin)
Bu, "+" ve "{1,}" ifadelerinin aynı olduğu anlamına gelir.
var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept
Zor yöntem:
var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]
'('
için /(/g
tüm değiştirmek (
unsurları - g
olduğu küresel RegExp için bayrak - bu tüm oluşumlarını aramak yüzden (
değil İlki
Bölme işlevlerinde daha fazla özelleştirme isteyenleriniz için, belirli bir dizeyi bölünecek karakter listesiyle ayıran özyinelemeli bir algoritma yazdım. Yukarıdaki yazıyı görmeden önce bunu yazdım. Umarım bazı sinirli programcılara yardımcı olur.
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);
Yukarıdaki örnek şunu döndürür: ["people", "and", "other", "things"]
Not: flatten
işlev Rosetta Kodundan alınmıştır
Ayırıcı olarak kullanmak istediğiniz tüm karakterleri tek tek veya toplu olarak normal bir ifadeye toplayabilir ve bunları split işlevine geçirebilirsiniz. Örneğin şunları yazabilirsiniz:
console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );
Ve çıktı:
["dasdnk", "asd", "naks", ":d", "skldma"]
Merhaba, örneğin Dize'de böl ve değiştir varsa 07:05:45
var hour = time.replace("PM", "").split(":");
Sonuç
[ '07', '05', '45' ]
ES6'da bunu başarmanın yeni bir yolu :
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));
Lütfen bu fonksiyonda not edin:
source
Yukarıdaki kodun sonucu:
a = "a=b,c:d"
array = ['=',',',':'];
for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }
bu özel bir karakter olmadan dizeyi döndürür.
@Brian cevabı için refactorum
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))
Bu ihtiyacım ana nedenlerinden biri hem /
ve hem de dosya yollarını bölmek olduğunu bulmak \
. Biraz zor bir normal ifade bu yüzden buraya referans için göndereceğim:
var splitFilePath = filePath.split(/[\/\\]/);
Kaldırmak istediklerinizin yerine, ne bırakmak istediğinizi belirtmeniz daha kolay olduğunu düşünüyorum.
Sanki sadece İngilizce kelimeler istiyormuş gibi, şöyle bir şey kullanabilirsiniz:
text.match(/[a-z'\-]+/gi);
Örnekler (snippet'i çalıştırın):
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>
@ Stephen-sweriduk çözümünden başlayarak (bu benim için daha ilginçti!), Daha genel ve yeniden kullanılabilir hale getirmek için biraz değiştirdim:
/**
* 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);
})
},
}
ve sonra
var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);
orijinal olarak geri verir:
[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]
Bunu yapmanın kolay bir yolu, dizenin her karakterini her bir sınırlayıcıyla işlemek ve bölünmeler dizisi oluşturmaktır:
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;
};
Kullanımı:
splix(string, delimiters...)
Misal:
splix("1.23--4", ".", "--")
İadeler:
["1", "23", "4"]
Böyle bir işlev için klasik bir uygulama sağlayacağım. Kod, JavaScript'in neredeyse tüm sürümlerinde çalışır ve bir şekilde optimumdur.
Sadece saf kod:
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);
}
Kodun oyun alanında çalıştığını görebilirsiniz: https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf
RegEx performansını bilmiyorum, ama burada RegEx yerel HashSet kullanır ve O (max (str.length, delimeter.length)) karmaşıklığı yerine çalışır:
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"]
En iyi yol değil, Çoklu ve Farklı ayırıcılar / sınırlayıcılarla Bölme için çalışır
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>
Regexp kullanıyorum:
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"]