逗号分隔的值除了双引号内的值

时间:2015-12-22 14:25:37

标签: javascript angularjs regex

我有一个在某些字段中格式化字符串的服务。基本上,当用户点击输入框(模糊)时,字符串将被清除非法字符,空格将替换为逗号。这很好,但我想允许用户在分组的单词周围添加双引号。在模糊时,这应该删除引号,但保持单词之间的空格,然后添加逗号。我已经尝试了所有的东西,但我不能让它发挥作用。以下是我目前的服务设置方式:

angular.module('testApp')
  .factory('formatStringService', [
    function () {
      return {
        formatString: function (string) {
          var styleStr = string;

          if (styleStr === undefined) {
            return;
          }
          styleStr = this.stringReplace(styleStr, '\n', ',');
          styleStr = this.stringReplace(styleStr, '\t', ',');
          styleStr = this.stringReplace(styleStr, ' ', ',');
          styleStr = this.stringReplace(styleStr, ';', ',');
          styleStr = this.newLine(styleStr);
          styleStr = this.validated(styleStr);

          for (var g = 0; g < 9; g++) {
            styleStr = this.stringReplace(styleStr, ',,', ',');
          }
          if (styleStr.charAt(styleStr.length - 1) === ',') {
            styleStr = styleStr.substr(0, (styleStr.length - 1));
          }
          if (styleStr.charAt(0) === '*') {
            styleStr = styleStr.substr(1, (styleStr.length - 1));
          }
          if (styleStr.charAt(styleStr.length - 1) === '*') {
            styleStr = styleStr.substr(0, (styleStr.length - 1));
          }
          return styleStr;
        },

        stringReplace: function (string, text, by) {
          var strLength = string.length,
            txtLength = text.length;
          if ((strLength === 0) || (txtLength === 0)) {
            return string;
          }
          var i = string.indexOf(text);
          if ((!i) && (text !== string.substring(0, txtLength))) {
            return string;
          }
          if (i === -1) {
            return string;
          }
          var newstr = string.substring(0, i) + by;
          if (i + txtLength < strLength) {
            newstr += this.stringReplace(string.substring(i + txtLength, strLength), text, by);
          }
          return newstr;
        },
        validated: function (string) {
          for (var i = 0, output = '', valid = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,~#+/\\*- '; i < string.length; i++) {
            if (valid.indexOf(string.charAt(i)) !== -1) {
              output += string.charAt(i);
            }
          }
          return output;
        },

        newLine: function (string) {
          for (var i = 0, output = ''; i < string.length; i++) {
            if (string.charCodeAt(i) !== 10) {
              output += string.charAt(i);
            }
          }
          return output;
        }
      };
    }
  ]);

输入字符串示例:1 2 3&#34;测试测试&#34; 7 8

应输出:1,2,3,测试,7,8

2 个答案:

答案 0 :(得分:1)

这是一个可以用于此目的的整洁的正则表达技巧:

var indices = [],
    re = /"[^"]*"|( )/g,
    str = '1 2 3 "test test" 7 8';

while ((match = re.exec(str)) !== null) {
    if (match[1] !== undefined) indices.push(match.index);
}

var split = [], prevIndex = -1;
indices.forEach(function(index) {
    split.push(str.slice(prevIndex + 1, index));
    prevIndex = index;
});

document.getElementById('output').innerText = split.join('\n');
<pre id='output'></pre>

我们在这里做的是匹配正则表达式/"[^"]*"|( )/ - 即“引号之间的东西”或“单个空格”。因此,如果我们找到一个引号,我们立即开始匹配“引号之间的东西”(因为正则表达式是贪婪的),因此引号之间的任何空格都只是在正则表达式的那一部分中被吞噬。

然后我们知道只有在双引号内时才会匹配( )。因此,我们将空间粘贴到捕获组中,然后对于每个匹配,我们只需检查捕获组是否存在。

答案 1 :(得分:1)

使用积极的展望,这样的事情应该这样做

'1 2 3 "test test" 7 8'.match(/(".*?"|[^"\s]+)(?=\s|$)/g)

Reg Exp Visualizer