2008-09-15 10 views
6

मुझे अन्यथा स्पेस से अलग सूची में सटीक वाक्यांशों (उद्धरणों में संलग्न) का समर्थन करने की आवश्यकता है। इस प्रकार अंतरिक्ष-चरित्र द्वारा संबंधित स्ट्रिंग को विभाजित करना अब पर्याप्त नहीं है।पार्सिंग स्ट्रिंग्स: शब्दों और वाक्यांशों को निकालने [जावास्क्रिप्ट]

उदाहरण:

input : 'foo bar "lorem ipsum" baz' 
output: ['foo', 'bar', 'lorem ipsum', 'baz'] 

मुझे आश्चर्य है कि इस जटिल पार्स या विभाजन और rejoin को ऑपरेशनों को करने से, एक भी रेगुलर एक्सप्रेशन से साथ प्राप्त किया जा सकता है या नहीं।

किसी भी मदद की सराहना की जाएगी!

उत्तर

12
var str = 'foo bar "lorem ipsum" baz'; 
var results = str.match(/("[^"]+"|[^"\s]+)/g); 

... जिस सरणी को आप ढूंढ रहे हैं उसे लौटाता है।
ध्यान दें, तथापि:

  • Bounding उद्धरण शामिल हैं, इसलिए replace(/^"([^"]+)"$/,"$1") परिणामों पर से हटाया जा सकता।
  • उद्धरण के बीच स्थान बरकरार रहेगा। इसलिए, यदि lorem और ipsum के बीच तीन रिक्त स्थान हैं, तो वे परिणाम में होंगे। आप परिणामों पर replace(/\s+/," ") चलाकर इसे ठीक कर सकते हैं।
  • अगर कोई समापन "ipsum के बाद (यानी एक गलत तरीके से उद्धृत वाक्यांश) आप के साथ खत्म होगी: ['foo', 'bar', 'lorem', 'ipsum', 'baz']
+1

इस के साथ ही समस्या यह है कि सभी उद्धरण हटा दिए जाते हैं है - यानी उद्धरण वर्ण खुद को खोजा नहीं कर रहे हैं। –

0
'foo bar "lorem ipsum" baz'.match(/"[^"]*"|\w+/g); 

सीमांकन उद्धरण शामिल हो हालांकि

0

एक साधारण नियमित अभिव्यक्ति है, लेकिन उद्धरण चिह्न छोड़ देंगे। जैसे

'foo bar "lorem ipsum" baz'.match(/("[^"]*")|([^\s"]+)/g) 
output: ['foo', 'bar', '"lorem ipsum"', 'baz'] 

संपादित करें: श्यामसुंदर से इसे करने के लिए पीटा, डबल जवाब

1

कैसे के बारे में के लिए खेद है,

output = /(".+?"|\w+)/g.exec(input) 

तो उद्धरण कम करने के लिए उत्पादन पर एक पास है।

बारी-बारी से,

output = /"(.+?)"|(\w+)/g.exec(input) 

तो खाली कैप्चर कम करने के लिए एक पास n उत्पादन करते हैं।

2

आज़माएं:

var input = 'foo bar "lorem ipsum" baz'; 
var R = /(\w|\s)*\w(?=")|\w+/g; 
var output = input.match(R); 

output is ["foo", "bar", "lorem ipsum", "baz"] 

नोट कोई अतिरिक्त दोहरे उद्धरण चिह्नों के आसपास रहे हैं lorem ipsum

हालांकि यह मानता है कि इनपुट में सही स्थान पर डबल कोट्स हैं:

var input2 = 'foo bar lorem ipsum" baz'; var output2 = input2.match(R); 
var input3 = 'foo bar "lorem ipsum baz'; var output3 = input3.match(R); 

output2 is ["foo bar lorem ipsum", "baz"] 
output3 is ["foo", "bar", "lorem", "ipsum", "baz"] 

और डबल कोट्स भाग निकले संभाल नहीं होगा (एक समस्या है?):

var input4 = 'foo b\"ar bar\" \"bar "lorem ipsum" baz'; 
var output4 = input4.match(R); 

output4 is ["foo b", "ar bar", "bar", "lorem ipsum", "baz"] 
0

तुम सिर्फ regex खुद के निर्माण करने के लिए कैसे सोच रहा है, तो आप Expresso की जाँच करने के लिए चाहते हो सकता है कर रहे हैं (Expresso link) ।नियमित अभिव्यक्तियों को कैसे विकसित करना है, यह जानने के लिए यह एक अच्छा टूल है ताकि आपको पता चल सके कि वाक्यविन्यास का क्या अर्थ है।

जब आपने अपनी अभिव्यक्ति बनाई है, तो आप .match पर इसे निष्पादित कर सकते हैं।

1

त्वरित प्रतिक्रियाओं के लिए बहुत बहुत धन्यवाद!

यहाँ एक, भावी पीढ़ी के लिए विकल्पों में से सारांश है:

var input = 'foo bar "lorem ipsum" "dolor sit amet" baz'; 
var terms = input.split(" "); 

var items = []; 
var buffer = []; 
for(var i = 0; i < terms.length; i++) { 
    if(terms[i].indexOf('"') != -1) { // outer phrase fragment -- N.B.: assumes quote is either first or last character 
     if(buffer.length === 0) { // beginning of phrase 
      //console.log("start:", terms[i]); 
      buffer.push(terms[i].substr(1)); 
     } else { // end of phrase 
      //console.log("end:", terms[i]); 
      buffer.push(terms[i].substr(0, terms[i].length - 1)); 
      items.push(buffer.join(" ")); 
      buffer = []; 
     } 
    } else if(buffer.length != 0) { // inner phrase fragment 
     //console.log("cont'd:", terms[i]); 
     buffer.push(terms[i]); 
    } else { // individual term 
     //console.log("standalone:", terms[i]); 
     items.push(terms[i]); 
    } 
    //console.log(items, "\n", buffer); 
} 
items = items.concat(buffer); 

//console.log(items); 
0

एक आसान है कि समझने के लिए और एक सामान्य समाधान:

var input = 'foo bar "lorem ipsum" baz'; 

output = input.match(/("[^"]+"|[^"\s]+)/g); 
output = input.match(/"[^"]*"|\w+/g); 
output = input.match(/("[^"]*")|([^\s"]+)/g) 
output = /(".+?"|\w+)/g.exec(input); 
output = /"(.+?)"|(\w+)/g.exec(input); 

रिकॉर्ड के लिए, यहाँ abomination मैं के साथ आया था है । सभी delimiters और 'शामिल' पात्रों के लिए काम करता है। इसके अलावा

"hello my name is 'jon delaware smith fred' I have a 'long name'" ....

एसी द्वारा जवाब लेकिन थोड़ा neater ...

की तरह एक सा जैसे शब्दों कि लंबाई में दो से अधिक शब्द हैं .... यानी सूचियों 'में शामिल हुए' का समर्थन करता है
function split(input, delimiter, joiner){ 
    var output = []; 
    var joint = []; 
    input.split(delimiter).forEach(function(element){ 
     if (joint.length > 0 && element.indexOf(joiner) === element.length - 1) 
     { 
      output.push(joint.join(delimiter) + delimiter + element); 
      joint = []; 
     } 
     if (joint.length > 0 || element.indexOf(joiner) === 0) 
     { 
      joint.push(element); 
     } 
     if (joint.length === 0 && element.indexOf(joiner) !== element.length - 1) 
     { 
      output.push(element); 
      joint = []; 
     } 
    }); 
    return output; 
    } 
0

यह एक बहुत ही देर से जवाब हो सकता है, लेकिन मैं

([\w]+|\"[\w\s]+\") 

http://regex101.com/r/dZ1vT6/72

0 जवाब देने में दिलचस्पी है

शुद्ध जावास्क्रिप्ट उदाहरण

'The rain in "SPAIN stays" mainly in the plain'.match(/[\w]+|\"[\w\s]+\"/g) 

आउटपुट:

["The", "rain", "in", ""SPAIN stays"", "mainly", "in", "the", "plain"] 
0

ES6 समाधान का समर्थन:

  • को छोड़कर अंदर
  • निकाला जा रहा है उद्धरण उद्धरण के लिए अंतरिक्ष से स्प्लिट नहीं बल्कि बैकस्लैश बच गए उद्धरण
  • के लिए
  • बच निकला uote बन बोली

कोड:

input.match(/\\?.|^$/g).reduce((p, c) => { 
     if(c === '"'){ 
      p.quote ^= 1; 
     }else if(!p.quote && c === ' '){ 
      p.a.push(''); 
     }else{ 
      p.a[p.a.length-1] += c.replace(/\\(.)/,"$1"); 
     } 
     return p; 
    }, {a: ['']}).a 

आउटपुट:

[ 'foo', 'bar', 'lorem ipsum', 'baz' ] 
संबंधित मुद्दे