正则表达式选择未用双引号括起来的分号

时间:2013-06-29 05:20:44

标签: regex

我有像

这样的字符串
a;b;"aaa;;;bccc";deef

我希望仅在;不在双引号内时才基于分隔符;拆分字符串。分裂后,它将是

 a
 b
"aaa;;;bccc"
 deef

我尝试使用look-behind,但我无法找到正确的正则表达式进行拆分。

4 个答案:

答案 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”)你可以分开“首先,然后假设所有偶数数组元素实际上都是字符串(并将奇数元素拆分为;令牌上的组成部分)。

如果你的字符串中有*,那么你首先要将它们转换为其他一些临时标记,你将在执行操作后转换回来。

这是一个小提琴......

http://jsfiddle.net/VW9an/

    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中的匹配项。

  • 交替|的左侧匹配完整的引用字符串
  • 右侧匹配任何既不是;也不是"
  • 的字符