मैं जावास्क्रिप्ट में कई विभाजकों के साथ एक स्ट्रिंग कैसे विभाजित करूं?


504

मैं जावास्क्रिप्ट में कई विभाजकों के साथ एक स्ट्रिंग कैसे विभाजित करूं? मैं दोनों अल्पविराम और स्थानों पर विभाजित करने की कोशिश कर रहा हूं लेकिन, AFAIK, JS का विभाजन फ़ंक्शन केवल एक विभाजक का समर्थन करता है।


3
मुझे यह समस्या उन फ़ाइल पथों को विभाजित करने की कोशिश कर रही थी जो विंडोज़ के तहत नोडज के साथ निर्मित किए गए थे। कभी-कभी एक ही रास्ते में आगे "/" और पीछे "" स्लैश होते थे।
फ्यूहरमैनटर

जवाबों:


707

पैरामीटर के रूप में एक regexp में पास करें:

js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!

जोड़ने के लिए संपादित:

आप सरणी ऋण 1 की लंबाई का चयन करके अंतिम तत्व प्राप्त कर सकते हैं:

>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"

... और यदि पैटर्न मेल नहीं खाता है:

>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"

1
आप अपने js> कंसोल के लिए क्या उपयोग कर रहे हैं?
कोर

4
राइनो, जावा में जावा के मोज़िला का कार्यान्वयन: mozilla.org/rhino (... या "sudo apt-get install rhino")।
हारून मेनापा

धन्यवाद। इससे संबंधित एक और प्रश्न जो मुझे करने की आवश्यकता है वह है छंटे हुए सरणी का अंतिम तत्व। अगर वहाँ कोई सरणी नहीं है तो उसे स्ट्रिंग को वापस करना चाहिए

2
क्या नियमित अभिव्यक्ति के साथ विभाजित होने पर विभाजकों को हटाने से बचने का कोई तरीका है?
एंडरसन ग्रीन

एक स्ट्रिंग "हेल्लो वर्ल्ड" के साथ-साथ एक अन्य चरित्र (या अन्य रेगेक्स), जैसे कि पाइप प्रतीक के लिए कैसे विभाजित किया जाए? (hello world)|\|जिन विविधताओं ने अभी तक बहुत काम नहीं किया है, उनकी कोशिश की । कोई विचार?
पौष्टिकता के बारे में

183

आप जावास्क्रिप्ट के विभाजन ऑपरेटर में एक रेगेक्स पास कर सकते हैं । उदाहरण के लिए:

"1,2 3".split(/,| /) 
["1", "2", "3"]

या, यदि आप एक साथ कई विभाजकों को केवल एक के रूप में कार्य करने देना चाहते हैं:

"1, 2, , 3".split(/(?:,| )+/) 
["1", "2", "3"]

(आपको गैर-कैप्चरिंग का उपयोग करना होगा (? :) परेंस क्योंकि अन्यथा यह परिणाम में वापस मिल जाता है। या आप हारून की तरह स्मार्ट हो सकते हैं और चरित्र वर्ग का उपयोग कर सकते हैं।)

(सफारी + एफएफ में परीक्षण किए गए उदाहरण)


3
यदि आपको एक के रूप में कार्य करने के लिए कई वर्णों की आवश्यकता है, जैसा कि "एक; #two; #new जर्सी" को कहते हैं, तो आप विभाजन फ़ंक्शन को केवल स्ट्रिंग पास कर सकते हैं "#;" "वन; #two; #new जर्सी"। split ("; #") [2] === "नई जर्सी"
Oskar Austegard

यदि आप एक से अधिक वर्णों पर विभाजित करने की आवश्यकता है, तो यह विधि वर्ण वर्गों से बेहतर काम करती है। |जेसी शो के अनुसार उन्हें अलग करें ।
devios1

मुझे आश्चर्य है कि अगर एक स्ट्रिंग को नियमित अभिव्यक्ति के साथ विभाजित करने से विभाजकों को हटाने से बचने का कोई तरीका है: यह उदाहरण विभाजकों को हटा देता है, लेकिन मुझे आशा है कि उन्हें हटाने के बिना एक स्ट्रिंग को विभाजित करना संभव है।
एंडरसन ग्रीन

1
@AndersonGreen यह वास्तव में आप क्या चाहते हैं पर निर्भर करता है; इस मामले में, कई विभाजक हैं, तो क्या आप उन सभी को रखना चाहते हैं? एक अलग आइटम के रूप में? पिछले आइटम में शामिल हो गए? अगला आइटम? यह मुझे अस्पष्ट लगता है। आप जो खोज रहे हैं उसके कुछ उदाहरणों के साथ एक नया प्रश्न बनाना चाहते हैं।
जेसी रूसक

@JesseRusak मेरा मतलब था कि सभी विभाजकों को अलग-अलग वस्तुओं के रूप में रखा जाए, ताकि विभाजकों की सूची का उपयोग करके एक स्ट्रिंग को टोकन किया जा सके।
एंडरसन ग्रीन

55

विभाजन का उपयोग करने के लिए एक और सरल लेकिन प्रभावी तरीका है + बार-बार जुड़ना।

"a=b,c:d".split('=').join(',').split(':').join(',').split(',')

अनिवार्य रूप से एक विभाजन में शामिल होने के बाद एक वैश्विक प्रतिस्थापन की तरह होता है इसलिए यह प्रत्येक विभाजक को अल्पविराम के साथ बदल देता है और एक बार सभी को प्रतिस्थापित करने के बाद यह अल्पविराम पर अंतिम विभाजन करता है

उपरोक्त अभिव्यक्ति का परिणाम है:

['a', 'b', 'c', 'd']

इस पर विस्तार करते हुए आप इसे किसी फ़ंक्शन में भी रख सकते हैं:

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;
}

उपयोग:

splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]

यदि आप इस कार्यक्षमता का उपयोग करते हैं, तो यह String.prototype.splitसुविधा के लिए रैपिंग पर विचार करने लायक भी हो सकता है (मुझे लगता है कि मेरा कार्य काफी सुरक्षित है - केवल विचार सशर्त का अतिरिक्त ओवरहेड है (मामूली) और तथ्य यह है कि इसमें सीमा तर्क के कार्यान्वयन का अभाव है अगर एक सरणी पारित हो गई है)।

splitMultiफ़ंक्शन को शामिल करना सुनिश्चित करें यदि नीचे इस दृष्टिकोण का उपयोग करते हुए बस इसे लपेटता है :)। यह भी ध्यान देने योग्य है कि कुछ लोग बिल्ट-इन का विस्तार करने पर भड़कते हैं (जैसा कि बहुत से लोग इसे गलत करते हैं और टकराव हो सकता है) इसलिए यदि संदेह में इस का उपयोग करने से पहले किसी और वरिष्ठ से बात करें या 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
    };

उपयोग:

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"] 

का आनंद लें!


3
आप क्यों लिखते हैं for(var i = 0; i < tokens.length; i++)और क्या नहीं for(var i = 1; i < tokens.length; i++)?
टिक

मुझे लगता है कि अनुकूलन याद किया गया था, आप सही हैं कि हम tokens[1]एक पुनरावृत्ति को बचाने के लिए शुरू कर सकते हैं tokens[0] == tempcharऔर हम खत्म tempcharहोने के बाद पुनरावृत्ति tokensकरने के बाद अलग हो जाते हैं। मैं उत्तर को तदनुसार अद्यतन करूँगा धन्यवाद @tic :)।
ब्रायन

20

इसे सरल रखें: (अपने RegEx में "[] +" जोड़ें "1 या अधिक"

इसका अर्थ है "+" और "{1,}" समान हैं।

var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept

2
अंत में "+" जोड़ें का अर्थ है 1 या अधिक
Asher

6
मैं कहूंगा कि यह न्यूनतम है, सरल नहीं है
डैरिल हेब्ब्स

+ और - -: के लिए, लेकिन यह भी रिक्त चार के बजाय \ _: var शब्द = text.split (/ [\ _ s.:;? ~!] \ + \ - [] \ r \ n / \] + /);
डिडिएर

12

ट्रिकी विधि:

var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]

3
यह गलत है क्योंकि .replace () सभी तत्वों को प्रतिस्थापित नहीं करता है:/

1
आप बदल सकते हैं '('के लिए /(/gसभी को बदलने के लिए (तत्वों - gहै वैश्विक तो यह की सभी घटनाओं के लिए खोज - रेगुलर एक्सप्रेशन के लिए झंडा (नहीं पहले एक
codename-

7

आप में से जो अपने बंटवारे समारोह में अधिक अनुकूलन चाहते हैं, मैंने एक पुनरावर्ती एल्गोरिथ्म लिखा है जो किसी दिए गए स्ट्रिंग को विभाजित करने के लिए वर्णों की एक सूची के साथ विभाजित करता है। उपरोक्त पोस्ट देखने से पहले मैंने यह लिखा था। मुझे आशा है कि यह कुछ निराश प्रोग्रामर की मदद करता है।

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);

रिटर्न के ऊपर उदाहरण: ["people", "and", "other", "things"]

नोट: flattenफ़ंक्शन रोसेटा कोड से लिया गया था


6

आप बस उन सभी पात्रों को लुभा सकते हैं जिन्हें आप विभाजक के रूप में या तो एकवचन में या सामूहिक रूप से एक नियमित अभिव्यक्ति में उपयोग करना चाहते हैं और उन्हें विभाजित फ़ंक्शन को पास करते हैं। उदाहरण के लिए आप लिख सकते हैं:

console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );

और उत्पादन होगा:

["dasdnk", "asd", "naks", ":d", "skldma"]

3

शायद आपको किसी विभाजक को दूसरे विभाजक में बदलने के लिए किसी प्रकार का स्ट्रिंग प्रतिस्थापित करना चाहिए ताकि आपके पास अपने विभाजन से निपटने के लिए केवल एक विभाजक हो।


3

उदाहरण के लिए नमस्ते अगर आप विभाजित हो चुके हैं और स्ट्रिंग 07:05:45 PM में बदल चुके हैं

var hour = time.replace("PM", "").split(":");

परिणाम

[ '07', '05', '45' ]

3

यहाँ 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));

कृपया इस समारोह में ध्यान दें:

  • कोई रेगेक्स शामिल नहीं है
  • यह उसी क्रम में विभाजित किए गए मान को लौटाता है जैसा कि यह प्रकट होता है source

उपरोक्त कोड का परिणाम होगा:

यहाँ छवि विवरण दर्ज करें


2
a = "a=b,c:d"

array = ['=',',',':'];

for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }

यह एक विशेष चेंजर के बिना स्ट्रिंग लौटाएगा।


2

@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))


1

मुझे लगता है कि मुख्य कारणों में से एक मुझे इसकी आवश्यकता है /और दोनों पर फ़ाइल पथ को विभाजित करना है \। यह एक मुश्किल regex का एक सा है तो मैं इसे यहाँ संदर्भ के लिए पोस्ट करेंगे:

var splitFilePath = filePath.split(/[\/\\]/);

1

मुझे लगता है कि यह आसान है यदि आप निर्दिष्ट करते हैं कि आप क्या छोड़ना चाहते हैं, बजाय इसके कि आप क्या हटाना चाहते हैं।

जैसे कि आपके पास केवल अंग्रेजी शब्द हैं, आप कुछ इस तरह का उपयोग कर सकते हैं:

text.match(/[a-z'\-]+/gi);

उदाहरण (रन स्निपेट):

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>


1

@ स्टीफन-स्वेरिडुक समाधान से शुरू (जो मेरे लिए अधिक दिलचस्प था!), मैंने इसे और अधिक सामान्य और पुन: प्रयोज्य बनाने के लिए थोड़ा संशोधित किया है:

/**
 * 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);
    })
  },

}

और फिर

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);

यह मूल के रूप में वापस देता है:

[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]

1

ऐसा करने का एक आसान तरीका स्ट्रिंग के प्रत्येक चरित्र को प्रत्येक सीमांकक के साथ संसाधित करना और विभाजन की एक सरणी का निर्माण करना है:

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;
};

उपयोग: splix(string, delimiters...)

उदाहरण: splix("1.23--4", ".", "--")

यह दिखाता है: ["1", "23", "4"]


1

मैं इस तरह के एक समारोह के लिए एक क्लासिक कार्यान्वयन प्रदान करेगा। कोड जावास्क्रिप्ट के लगभग सभी संस्करणों में काम करता है और किसी भी तरह इष्टतम है।

  • यह रेगेक्स का उपयोग नहीं करता है, जिसे बनाए रखना कठिन है
  • यह जावास्क्रिप्ट की नई सुविधाओं का उपयोग नहीं करता है
  • यह कई .split () .join () इनवोकेशन का उपयोग नहीं करता है जिसके लिए अधिक कंप्यूटर मेमोरी की आवश्यकता होती है

बस शुद्ध कोड:

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);
}

आप खेल के मैदान में चलने वाला कोड देख सकते हैं: https://codeguppy.com/code.html?IJI0E4OGnkyTZnosAzf


0

मुझे RegEx के प्रदर्शन का पता नहीं है, लेकिन यहाँ RegEx के लिए एक और विकल्प है मूल HashSet का लाभ उठाता है और O (अधिकतम (str.length, delimeter.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"]

11
हाँ, कैसे के बारे में आप वास्तव में कुछ है कि आप लिख परीक्षण? jsperf.com/slice-vs-custom यह दर्शाता है कि आपका कोड वास्तव में इस उदाहरण में 10 गुना धीमा है। आपने क्या विचार दिया कि 2 बार स्लाइस, 2 बार कॉनैट, 1 टाइम स्प्लिट, 1 टाइम शिफ्ट और नो लेंथ कैशिंग का उपयोग करना परफॉर्मेंस फ्रेंडली है?
पेटर

मैंने कोड को अपडेट कर दिया है, अब बिना किसी बदलाव, विभाजन या आदि के साथ केवल न्यूनतम मात्रा में स्लाइस है
ओरहुन अल्फा ओरल

0

सबसे अच्छा तरीका नहीं है, लेकिन कई और अलग अलग विभाजक / सीमांकक के साथ विभाजित करने के लिए काम करता है

एचटीएमएल

<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>

जावास्क्रिप्ट

<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>

-3

मैं regexp का उपयोग करता हूं:

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"]

1
इस के साथ कुछ नहीं करता खोल देना , बस शब्द।
नाथन तुग्गी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.