我有像
这样的字符串a;b;"aaa;;;bccc";deef
我希望仅在;
不在双引号内时才基于分隔符;
拆分字符串。分裂后,它将是
a
b
"aaa;;;bccc"
deef
我尝试使用look-behind,但我无法找到正确的正则表达式进行拆分。
答案 0 :(得分:9)
正则表达式可能不是正确的工具。如果可能,您应该使用CSV库,指定;
作为分隔符,"
作为引号字符,这应该为您提供您要查找的确切字段。
这里所说的是一种方法,通过确保;
之间存在偶数个引号,我们正在考虑字符串的分割和结束。
;(?=(([^"]*"){2})*[^"]*$)
示例:http://www.rubular.com/r/RyLQyR8F19
如果您可以在字符串中转义引号,例如a;"foo\"bar";c
,则会中断。
使用Python的csv module:
,这是一个更清晰的例子import csv, StringIO
reader = csv.reader(StringIO.StringIO('a;b;"aaa;;;bccc";deef'),
delimiter=';', quotechar='"')
for row in reader:
print '\n'.join(row)
答案 1 :(得分:2)
这有点难看,但是如果你没有在你引用的字符串里面(意思是你没有看起来像这样的字符串(“foo bar \”badoo \“goo”)你可以分开“首先,然后假设所有偶数数组元素实际上都是字符串(并将奇数元素拆分为;令牌上的组成部分)。
如果你的字符串中有*,那么你首先要将它们转换为其他一些临时标记,你将在执行操作后转换回来。
这是一个小提琴......
var str = 'abc;def;ghi"some other dogs say \\"bow; wow; wow\\". yes they do!"and another; and a fifth'
var strCp = str.replace(/\\"/g,"--##--");
var parts = strCp.split(/"/);
var allPieces = new Array();
for(var i in parts){
if(i % 2 == 0){
var innerParts = parts[i].split(/\;/)
for(var j in innerParts)
allPieces.push(innerParts[j])
}
else{
allPieces.push('"' + parts[i] +'"')
}
}
for(var a in allPieces){
allPieces[a] = allPieces[a].replace(/--##--/g,'\\"');
}
console.log(allPieces)
答案 2 :(得分:2)
正则表达式只会变得更加混乱,即使是微小的变化也会中断。使用任何脚本语言的csv
解析器最好。 Perl内置模块(因此,如果有任何限制,您无需从CPAN下载),Text::ParseWords允许您指定分隔符,以便您不限于,
。这是一个示例代码段:
#!/usr/local/bin/perl
use strict;
use warnings;
use Text::ParseWords;
my $string = 'a;b;"aaa;;;bccc";deef';
my @ary = parse_line(q{;}, 0, $string);
print "$_\n" for @ary;
的输出强> 的
a
b
aaa;;;bccc
deef
答案 3 :(得分:1)
在战斗结束后回答很长时间,因为没有人使用对我来说最简单的方式。
一旦理解了Match All and Split are Two Sides of the Same Coin,就可以使用这个简单的正则表达式:
"[^"]*"|[^";]+
查看Regex Demo中的匹配项。
|
的左侧匹配完整的引用字符串;
也不是"