जावास्क्रिप्ट और रेगेक्स: विभाजित स्ट्रिंग और विभाजक रखें


131

मेरे पास एक स्ट्रिंग है:

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc"

और मैं इस स्ट्रिंग को <br />एक विशेष चरित्र के बाद सीमांकक के साथ विभाजित करना चाहूंगा ।

ऐसा करने के लिए, मैं इसका उपयोग कर रहा हूं:

string.split(/<br \/>&#?[a-zA-Z0-9]+;/g);

मुझे वही मिल रहा है जो मुझे चाहिए, सिवाय इसके कि मैं परिसीमन खो रहा हूं। यहाँ उदाहरण है: http://jsfiddle.net/JwrZ6/1/

मैं परिसीमन कैसे कर सकता हूं?


यदि आप पहले से ही सीमांकक जानते हैं, तो बस क्यों नहीं ... var delim = "<br/>";?
एंड्रियास वोंग

धन्यवाद @SiGanteng, मैं पहले से ही परिसीमन जानता हूं, लेकिन मैं इसे अपने उदाहरण के लिए काम नहीं कर सकता। मुझे विशेष चरित्र के बाद परिसीमन को <br /> रखने की आवश्यकता है क्योंकि कभी-कभी मेरे पास <br /> विशेष वर्ण का पालन नहीं हो सकता है और इसे किसी को विभाजित करने की आवश्यकता नहीं है।
मिलो

2
अच्छा सवाल है, मेरे पास एक ऐसा ही मामला है जहां परिसीमन जानने से मदद नहीं मिलती है। मैं "] और [" पर बंट रहा हूं। तो वास्तव में मेरा सीमांकक "&" है, लेकिन उस पर विभाजन पर्याप्त सटीक नहीं है, मुझे उचित विभाजन निर्धारित करने के लिए कोष्ठक की आवश्यकता है। हालाँकि, मुझे अपने विभाजित तारों में उन कोष्ठकों की आवश्यकता है। प्रत्येक में 1, दोनों ओर।
पांडावुड

जवाबों:


104

उपयोग (पॉजिटिव) लुकहेड का ताकि नियमित अभिव्यक्ति यह बताए कि विशेष चरित्र मौजूद है, लेकिन वास्तव में यह मेल नहीं खाता:

string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g);

इसे कार्रवाई में देखें:

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc";
console.log(string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g));


जब मैं इस कोड का उपयोग करता हूं, तो यह 0प्रत्येक स्ट्रिंग के अंत में जोड़ता है
कीबोर्ड-योद्धा

2
आपके द्वारा दिए गए लिंक में मुझे सकारात्मक रूप के बारे में कुछ भी नहीं मिल रहा है।
पॉल क्रिस जोन्स

@PaJJones सामग्री को हस्तक्षेप के समय में स्थानांतरित किया गया था। मुझे बताने के लिए धन्यवाद, मैंने लिंक को ठीक कर दिया।
जॉन

179

मैं समान लेकिन मामूली अलग समस्या थी। वैसे भी, यहां तीन अलग-अलग परिदृश्यों के उदाहरण हैं जहां अपराधी को रखना है।

"1、2、3".split("、") == ["1", "2", "3"]
"1、2、3".split(/(、)/g) == ["1", "、", "2", "、", "3"]
"1、2、3".split(/(?=、)/g) == ["1", "、2", "、3"]
"1、2、3".split(/(?!、)/g) == ["1、", "2、", "3"]
"1、2、3".split(/(.*?、)/g) == ["", "1、", "", "2、", "3"]

चेतावनी: चौथा केवल एकल पात्रों को विभाजित करने के लिए काम करेगा। कनेक्टर्सफैन एक विकल्प प्रस्तुत करता है :

// Split a path, but keep the slashes that follow directories
var str = 'Animation/rawr/javascript.js';
var tokens = str.match(/[^\/]+\/?|\//g);

3
मैं तीसरे उदाहरण की तरह कुछ ढूंढ रहा था, लेकिन यह केवल तभी काम करता है जब तत्व केवल एक ही वर्ण हों - यह अलग-अलग वर्णों में विभाजित हो जाएगा। मुझे अंत में थकाऊ RegExp.exec मार्ग पर जाना पड़ा ।
गॉर्डन

2
मुझे समझ में नहीं आ रहा है कि हर कोई क्यों उपयोग कर रहा है / g
सरसापारिला

1
पूर्ण शब्दों के लिए इस regex "1、2 use3" का उपयोग कैसे करें। उदाहरण के लिए "foo1, foo2, foo3,"
वाल्टारी

आप जीनियस हैं!। जहाँ आपको यह पता चलता है कि यह काम करने का तरीका क्या है? आपको g
पेरी मिमोन

1
.matchइन उदाहरणों के लिए गैर-लालची समाधान का अनुवाद : "11、22、33".match(/.*?、|.+$/g)-> ["11、", "22、", "33"]। नोट /gसंशोधक मिलान के लिए महत्वपूर्ण है।
बेनी चेर्नियाव्स्की-पास्किन

57

यदि आप सीमांकक को परांठे में लपेटते हैं तो यह लौटे हुए सरणी का हिस्सा होगा।

string.split(/(<br \/>&#?[a-zA-Z0-9]+);/g);
// returns ["aaaaaa", "<br />&dagger;", "bbbb", "<br />&Dagger;", "cccc"]

निर्भर करता है कि आप किस भाग को बदलना चाहते हैं, जो आपके मेल खाते हैं

string.split(/(<br \/>)&#?[a-zA-Z0-9]+;/g);
// returns ["aaaaaa", "<br />", "bbbb", "<br />", "cccc"]

आप अक्षर string.split (/) (& #; [a-z0 -9] +; / gi) के मामले को नजरअंदाज करके अभिव्यक्ति में सुधार कर सकते हैं;

और आप इस तरह के पूर्वनिर्धारित समूहों के लिए मेल कर सकते हैं: \dबराबर [0-9]और \wबराबर [a-zA-Z0-9_]। इसका मतलब है कि आपकी अभिव्यक्ति इस तरह दिख सकती है।

string.split(/<br \/>(&#?[a-z\d]+;)/gi);

जावास्क्रिप्टकिट पर एक अच्छा नियमित अभिव्यक्ति संदर्भ है


4
इससे भी बेहतर, मैं नहीं जानता कि हम केवल सीमांकक का एक हिस्सा रख सकते हैं। वास्तव में मुझे केवल विशेष चार रखने की आवश्यकता है, मैं इसे इसके साथ कर सकता हूं: string.split (/ <br \ // (& # ([[a-zA-Z0-9] +;); g / g);
मिलो

1
आप शब्दों के मामले को अनदेखा करके अपनी अभिव्यक्ति को अनुकूलित कर सकते हैं। या एक पूर्वनिर्धारित चरित्र वर्ग के लिए मैच। मैं अपना जवाब अपडेट करूंगा।
टॉरस्टेन वाल्टर

2
यह इतना कम क्यों है .. इसका सही और इतना लचीला
टोफंडेल

2
यह निश्चित रूप से सबसे आसान तरीका है, और सबसे पठनीय वाक्यविन्यास है।
तिमार इवो बैटिस

4

यहाँ भी इसका जवाब दिया कि जावास्क्रिप्ट स्प्लिट रेगुलर एक्सप्रेशन डिमाइटर रखते हैं

रेगेक्स उदाहरण में (? = पैटर्न) लुकहेड पैटर्न का उपयोग करें

var string = '500x500-11*90~1+1';
string = string.replace(/(?=[$-/:-?{-~!"^_`\[\]])/gi, ",");
string = string.split(",");

यह आपको निम्नलिखित परिणाम देगा।

[ '500x500', '-11', '*90', '~1', '+1' ]

सीधे भी विभाजित किया जा सकता है

string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi);

वही परिणाम दे रहा है

[ '500x500', '-11', '*90', '~1', '+1' ]

जॉन के स्वीकृत उत्तर के अनुसार, तुरंत ही विभाजित क्यों नहीं किया गया?
गॉर्डन

@ गोर्डन ... :) मैं बस इतना ही कर सकता था ... कोड को अपडेट किया ... चीयर्स
फ्राई

2

मैंने jichi के उत्तर में संशोधन किया, और इसे एक फ़ंक्शन में रखा, जो कई अक्षरों का समर्थन करता है।

String.prototype.splitAndKeep = function(separator, method='seperate'){
    var str = this;
    if(method == 'seperate'){
        str = str.split(new RegExp(`(${separator})`, 'g'));
    }else if(method == 'infront'){
        str = str.split(new RegExp(`(?=${separator})`, 'g'));
    }else if(method == 'behind'){
        str = str.split(new RegExp(`(.*?${separator})`, 'g'));
        str = str.filter(function(el){return el !== "";});
    }
    return str;
};

jichi के उत्तर 3 विधि इस फ़ंक्शन में काम नहीं करेंगे, इसलिए मैंने 4 वीं विधि ली, और समान परिणाम प्राप्त करने के लिए रिक्त स्थान हटा दिए।

संपादित करें: दूसरी विधि जो char1 या char2 को विभाजित करने के लिए एक सरणी को स्वीकार करती है

String.prototype.splitAndKeep = function(separator, method='seperate'){
    var str = this;
    function splitAndKeep(str, separator, method='seperate'){
        if(method == 'seperate'){
            str = str.split(new RegExp(`(${separator})`, 'g'));
        }else if(method == 'infront'){
            str = str.split(new RegExp(`(?=${separator})`, 'g'));
        }else if(method == 'behind'){
            str = str.split(new RegExp(`(.*?${separator})`, 'g'));
            str = str.filter(function(el){return el !== "";});
        }
        return str;
    }
    if(Array.isArray(separator)){
        var parts = splitAndKeep(str, separator[0], method);
        for(var i = 1; i < separator.length; i++){
            var partsTemp = parts;
            parts = [];
            for(var p = 0; p < partsTemp.length; p++){
                parts = parts.concat(splitAndKeep(partsTemp[p], separator[i], method));
            }
        }
        return parts;
    }else{
        return splitAndKeep(str, separator, method);
    }
};

उपयोग:

str = "first1-second2-third3-last";

str.splitAndKeep(["1", "2", "3"]) == ["first", "1", "-second", "2", "-third", "3", "-last"];

str.splitAndKeep("-") == ["first1", "-", "second2", "-", "third3", "-", "last"];

1

एक एक्सटेंशन फ़ंक्शन स्ट्रिंग स्ट्रिंग के साथ या RegEx करता है और सीमांकक को दूसरे पैरामीटर के अनुसार आगे या पीछे रखा जाता है।

    String.prototype.splitKeep = function (splitter, ahead) {
        var self = this;
        var result = [];
        if (splitter != '') {
            var matches = [];
            // Getting mached value and its index
            var replaceName = splitter instanceof RegExp ? "replace" : "replaceAll";
            var r = self[replaceName](splitter, function (m, i, e) {
                matches.push({ value: m, index: i });
                return getSubst(m);
            });
            // Finds split substrings
            var lastIndex = 0;
            for (var i = 0; i < matches.length; i++) {
                var m = matches[i];
                var nextIndex = ahead == true ? m.index : m.index + m.value.length;
                if (nextIndex != lastIndex) {
                    var part = self.substring(lastIndex, nextIndex);
                    result.push(part);
                    lastIndex = nextIndex;
                }
            };
            if (lastIndex < self.length) {
                var part = self.substring(lastIndex, self.length);
                result.push(part);
            };
            // Substitution of matched string
            function getSubst(value) {
                var substChar = value[0] == '0' ? '1' : '0';
                var subst = '';
                for (var i = 0; i < value.length; i++) {
                    subst += substChar;
                }
                return subst;
            };
        }
        else {
            result.add(self);
        };
        return result;
    };

कसौटी:

    test('splitKeep', function () {
        // String
        deepEqual("1231451".splitKeep('1'), ["1", "231", "451"]);
        deepEqual("123145".splitKeep('1', true), ["123", "145"]);
        deepEqual("1231451".splitKeep('1', true), ["123", "145", "1"]);
        deepEqual("hello man how are you!".splitKeep(' '), ["hello ", "man ", "how ", "are ", "you!"]);
        deepEqual("hello man how are you!".splitKeep(' ', true), ["hello", " man", " how", " are", " you!"]);
        // Regex
        deepEqual("mhellommhellommmhello".splitKeep(/m+/g), ["m", "hellomm", "hellommm", "hello"]);
        deepEqual("mhellommhellommmhello".splitKeep(/m+/g, true), ["mhello", "mmhello", "mmmhello"]);
    });

0

मैं इसका उपयोग कर रहा हूं:

String.prototype.splitBy = function (delimiter) {
  var 
    delimiterPATTERN = '(' + delimiter + ')', 
    delimiterRE = new RegExp(delimiterPATTERN, 'g');

  return this.split(delimiterRE).reduce((chunks, item) => {
    if (item.match(delimiterRE)){
      chunks.push(item)
    } else {
      chunks[chunks.length - 1] += item
    };
    return chunks
  }, [])
}

सिवाय इसके कि आपको गड़बड़ नहीं करनी चाहिए String.prototype, इसलिए यहां एक फ़ंक्शन संस्करण है:

var splitBy = function (text, delimiter) {
  var 
    delimiterPATTERN = '(' + delimiter + ')', 
    delimiterRE = new RegExp(delimiterPATTERN, 'g');

  return text.split(delimiterRE).reduce(function(chunks, item){
    if (item.match(delimiterRE)){
      chunks.push(item)
    } else {
      chunks[chunks.length - 1] += item
    };
    return chunks
  }, [])
}

तो आप कर सकते हैं:

var haystack = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc"
var needle =  '<br \/>&#?[a-zA-Z0-9]+;';
var result = splitBy(haystack , needle)
console.log( JSON.stringify( result, null, 2) )

और आप के साथ समाप्त होगा:

[
  "<br />&dagger; bbbb",
  "<br />&Dagger; cccc"
]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.