正则表达式在引号外的特定字符上拆分字符串

时间:2014-03-19 10:41:57

标签: javascript regex

如何在保留引用字符串的情况下拆分此行

>div#a.more.style.ui[url="in.tray"]{value}

分割的字符是

> # . [ {

产量:

>div
#a
.more
.style
.ui
[url="in.tray"]
{value}

目前的努力是:

\>|\[|\{|#|\.?(?:(["'])(?:\\?.)*?\1)*

"in.tray"分开。

更新1:

解决方案需要是基于正则表达式的,因为模式是从现有代码中JS对象的键组装而成的,它们是:

JSObject
    '>': function ...
    '^': function ...
    '[': function ...
     ...

使用函数作为回调来处理正则表达式的输出。

目标字符串是一个Emmet宏,可以包含要开始的普通字符,以及至少^$的可能重复,将被视为单独的元素,例如:

p>div>div>span^h2^^h1>div#a.li^mo+re.st*yle.ui[url="in.tray"]{value}$$$

根据@tim-pietzcker使用.match()但最后一个匹配为空的当前努力已过滤掉:

[a-z$^+*>#.[{]{0,1}(?:"[^"]*"|[^"$^+*>#.[{]){0,}

3 个答案:

答案 0 :(得分:4)

不要使用split(),这很容易:

result = subject.match(/[>#.[{](?:"[^"]*"|[^">#.[{])+/g);

live on regex101.com

<强>解释

[>#.[{]     # Match a "splitting" character
(?:         # Start of group to match either...
 "[^"]*"    # a quoted string
|           # or
 [^">#.[{]  # any character except quotes and "splitting" characters
)+          # Repeat at least once.

答案 1 :(得分:1)

只使用一个正则表达式的解决方案很难实现。

我可以提出这个建议:

var i=0, s= '>div#a.more.style.ui[url="in.tray"]{value}';
var tokens = s.replace(/("[^"]+"|[^"\s]+)/g, function(v){
     return (i++)%2 ? v : v.replace(/([.>#\[{])/g, '@@@$1')}
).split('@@@').filter(Boolean);

(将@@@替换为您知道不在字符串中的字符串。

想法是

  1. 将引号和引号中的字符串中的初始字符串拆分为字符串(或者,后者用引号括起来)(不是真正的拆分,只是概念拆分)
  2. 在引号之外,在分隔符
  3. 之前添加@@@
  4. 拆分@@@加入的字符串
  5. 使用filter
  6. 删除(潜在)空字符串

答案 2 :(得分:-1)

我确实想知道Regex是否真的是这种情况下的方法。我知道这被标记为regex,但我想分享一个非正则表达式,只处理每个字符:

var string = '>div#a.more.style.ui[url="in.tray"]{value}'
var delims = [ '>', '#', '.', '[', '{' ];
var inQuotes = false;
var parts = [];
var part = string[0]; // Start with first character

for(i = 1; i < string.length; i++) {
  var character = string[i];

  if(character == '"') inQuotes = !inQuotes;

  if(!inQuotes && delims.indexOf(character) > -1) {
    parts.push(part);
    part = character;
  } else part += character;

  if(i == string.length-1) parts.push(part);
}

console.log(parts);

输出:

[ '>div',
  '#a',
  '.more',
  '.style',
  '.ui',
  '[url="in.tray"]',
  '{value}' ]

inQuotes商家不会对引号内的转义引号起作用,即"He said, \"hi there!\"",但对于像这样的简单案例,它会起作用。您可以通过将之前的字符与&#34; \&#34;进行比较来扩展它以检查报价是否是报价中的转义报价。并且检查isQuotes目前是true我认为,但可能有更好的解决方案。

就可读性而言,我认为像这样的方法比Regex更受欢迎。