如何在保留引用字符串的情况下拆分此行
>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,}
答案 0 :(得分:4)
不要使用split()
,这很容易:
result = subject.match(/[>#.[{](?:"[^"]*"|[^">#.[{])+/g);
<强>解释强>
[>#.[{] # 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);
(将@@@
替换为您知道不在字符串中的字符串。
想法是
filter
答案 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更受欢迎。