允许空格时将正则表达式与下一个特殊字符匹配

时间:2016-07-06 07:32:47

标签: javascript regex

我正在使用Javascript使用正则表达式提取字符串的一部分。

我有一个字符串:

lorem ipsum !bang #hash #hash2 ^caret word @at sym

我试图从各种字符开始拉出单词 - 有时它们可​​以有一个空格,每种类型可以有多个。所以我想将这个字符串转换为一组值,例如:

text: "lorem ipsum"
!: "bang"
#: ["hash", "hash2"]
^: "caret word"
@: "at sym"

我目前的正则表达式为/ ([!#^@>\/*-]\w+)/gm。这种方法有效,但它与空格不匹配 - 所以从上面的示例中它只为caret生成^,而不是整个caret word

我的代码是:

var result = {};

var re = / ([!#^@>\/*-]\w+)/gm;
var m;

var firstSpecialCharIndex = inputString.search(/ [!#^@>\/*-]/);
result["text"] = inputString.substring(0, firstSpecialCharIndex);

while ((m = re.exec(inputString)) !== null) {
  if (m.index === re.lastIndex) {
    re.lastIndex++;
  }

  var index = m[1].substring(0,1);
  if(result[index] == null)
    result[index] = [];
  result[index].push(m[1].substring(1));
}

有没有人知道我如何匹配下一个特殊字符,包括多个单词之间的空格(但不是后面的空格到下一个特殊字符)?非常感谢

3 个答案:

答案 0 :(得分:1)

为简单起见,我删除text部分。你可以使用前瞻

([!#^@>\/*-])(.*?)(?=\s[!#^@>\/*-]|$)

<强> Regex Demo

第1组包含符号,第2组包含文本,您可以根据需要修剪结果。

JS Demo

&#13;
&#13;
var inputString = "lorem ipsum !bang #hash #hash2 ^caret word @at sym";

var result = {};

var re = /([!#^@>\/*-])(.*?)(?=\s[!#^@>\/*-]|$)/gm;
var m;

var firstSpecialCharIndex = inputString.search(/ [!#^@>\/*-]/);
result["text"] = inputString.substring(0, firstSpecialCharIndex);

while ((m = re.exec(inputString)) !== null) {
    var index = m[1];
    if(result[index] == null) {
        result[index] = [];
    }
    result[index].push(m[2].trim());
}
document.writeln("<pre>" + JSON.stringify(result) + "</pre>");
&#13;
&#13;
&#13;

答案 1 :(得分:0)

试试这个:

/ ((?:[!#^@>\/*-]\w+)(?: [^!#^@>\/*-]\w+)*)/gm

regex101 example

括号中的

?:使得子模式不会进行任何捕获。删除它,看看发生了什么变化。

Chrome

中测试了此代码
var inputString = "lorem ipsum !bang #hash #hash2 ^long caret word @at sym";

var result = {};

//var re = / ([!#^@>\/*-]\w+)/gm;
var re = / ((?:[!#^@>\/*-]\w+)(?: [^!#^@>\/*-]\w+)*)/gm;
var m;

var firstSpecialCharIndex = inputString.search(/ [!#^@>\/*-]/);
result["text"] = inputString.substring(0, firstSpecialCharIndex);

while ((m = re.exec(inputString)) !== null) {
    if (m.index === re.lastIndex) {
        re.lastIndex++;
    }

    var index = m[1].substring(0,1);
    if(result[index] == null) {
        result[index] = [];
    }
    result[index].push(m[1].substring(1));
}
console.log(result);

效果很好。

答案 2 :(得分:0)

只是对替代方案的建议,但如果使用正则表达式在特殊字符上进行拆分(在非捕获空间和前瞻字母数字字符之前),同时保留捕获的特殊字符,则可以将逻辑重写为:

var inputString = 'lorem ipsum !bang #hash #hash2 ^caret word @at sym'

var rx = /(?:\s)([!#^@>\/*-](?=\w))/;
var arr = inputString.split(rx);
var result = {text:  arr[0]};
for(var i = 1; i < arr.length; i++){
		var ind = arr[i++], val = arr[i];
    var coll = (result[ind] = result[ind] || []);
    coll.push(val);    
}

console.log(JSON.stringify(result));

主要优点是表达式中不重复特殊字符。一个小的次要问题是搜索只执行一次('text'部分只是结果中的第一个元素)。 它还可以在单​​词中间使用多个单词和/或特殊字符,例如'lorem ipsum !bang #ha/sh adfa #ha3sh2 ^caret word asdf @at sym'