解析字符串:提取单词和短语[JavaScript]

时间:2020-03-05 18:54:02  来源:igfitidea点击:

我需要在用空格分隔的术语列表中支持确切的短语(用引号引起来)。
因此,用空格字符分割各个字符串已不再足够。

例子:

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

我想知道是否可以通过单个RegEx而不是执行复杂的解析或者拆分和重新合并操作来实现。

任何帮助将不胜感激!

解决方案

回答

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

包围引号虽然被包括在内

回答

一个简单的正则表达式就可以,但是保留引号。例如

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

编辑:被shyamsundar打败了,对不起,双重回答

回答

怎么样,

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

然后对输出进行传递以丢失引号。

交替,

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

然后执行pass n输出以丢失空捕获。

回答

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

...返回我们要查找的数组。
但是请注意:

  • 包含引号,因此可以在结果上使用replace(/ ^"([^"] +)" $ /," $ 1")删除。
  • 引号之间的空格将保持不变。因此,如果loremipsum之间有三个空格,它们将出现在结果中。我们可以通过在结果上运行replace(/ \ s + /,"")来解决此问题。
  • 如果在" ipsum"之后没有结束的"""(即引用不正确的短语),我们将得到:[[foo],'bar','lorem','ipsum','baz']

回答

试试这个:

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

回答

如果我们只是想知道如何自己构建正则表达式,则可能需要查看Expresso(Expresso链接)。这是学习如何构建正则表达式的好工具,以便我们了解语法的含义。

构建自己的表达式后,可以对其执行.match

回答

非常感谢快速回复!

这是后代选项的摘要:

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

作为记录,这是我想出的可憎之处:

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