5

我有类似的字符串

a;b;"aaa;;;bccc";deef

;仅当;不在双引号内时,我才想根据分隔符拆分字符串。所以分手后会

 a
 b
"aaa;;;bccc"
 deef

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

4

4 回答 4

9

正则表达式可能不是解决此问题的正确工具。如果可能,您应该使用 CSV 库,指定;为分隔符和"引号字符,这应该为您提供您正在寻找的确切字段。

话虽如此,这是一种通过确保在;我们正在考虑的拆分处和字符串末尾之间有偶数个引号来起作用的方法。

;(?=(([^"]*"){2})*[^"]*$)

示例:http ://www.rubular.com/r/RyLQyR8F19

如果您可以在字符串中使用转义引号,例如a;"foo\"bar";c.

这是一个使用 Python 的csv 模块的更简洁的示例:

import csv, StringIO
reader = csv.reader(StringIO.StringIO('a;b;"aaa;;;bccc";deef'),
                    delimiter=';', quotechar='"')
for row in reader:
    print '\n'.join(row)
于 2013-06-29T05:28:45.710 回答
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)
于 2013-06-29T05:31:09.853 回答
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
于 2013-06-29T05:42:34.377 回答
1

匹配所有而不是拆分

战斗后很久才回答,因为没有人使用我认为最简单的方式。

一旦您了解Match All 和 Split 是同一枚硬币的两个面,您就可以使用这个简单的正则表达式:

"[^"]*"|[^";]+

请参阅Regex Demo中的匹配项。

  • 交替的左侧|匹配完整的引号字符串
  • 右侧匹配任何既不是;也不是的字符"
于 2014-08-08T10:58:31.673 回答