我想找一个正则表达式,它可以挑出所有落在引号集之外的逗号。举例来说:
'foo' => 'bar', 'foofoo' => 'bar,bar'
字符串这将挑出第1行'bar',之后的单个逗号我真的不在乎单引号和双引号。有人有什么想法吗?我觉得这应该是可能的readaheads,但我的regex fu太弱。
'bar',
thigvfpy1#
这将匹配任何字符串,直到并包括第一个非引号“,”。这就是你想要的吗
/^([^"]|"[^"]*")*?(,)/
字符串如果你想要所有这些(作为一个反例,那个说这不可能的人),你可以写:
/(,)(?=(?:[^"]|"[^"]*")*$)/
型这将匹配所有这些。因此
'test, a "comma,", bob, ",sam,",here'.gsub(/(,)(?=(?:[^"]|"[^"]*")*$)/,';')
型用分号替换引号内的所有逗号 not,并生成:
'test; a "comma,"; bob; ",sam,";here'
型如果你需要它跨换行符工作,只需添加m(多行)标志。
lg40wkob2#
下面的正则表达式将匹配双引号外的所有逗号,
,(?=(?:[^"]*"[^"]*")*[^"]*$)
字符串DEMO
或(仅PCRE)
"[^"]*"(*SKIP)(*F)|,
型"[^"]*"匹配所有双引号块。也就是说,在这个buz,"bar,foo"输入中,这个正则表达式将只匹配"bar,foo"。现在下面的(*SKIP)(*F)使匹配失败。然后,它移动到|符号旁边的模式,并尝试匹配剩余字符串中的字符。也就是说,在我们的输出中,|旁边的,将只匹配buz后面的逗号。请注意,这不会匹配双引号内的逗号,因为我们已经跳过了双引号部分。DEMO的下面的正则表达式将匹配双引号内的所有逗号,
"[^"]*"
buz,"bar,foo"
"bar,foo"
(*SKIP)(*F)
|
,
buz
,(?!(?:[^"]*"[^"]*")*[^"]*$)
型DEMO的
g2ieeal73#
虽然可以使用正则表达式(我和其他人一样喜欢滥用正则表达式),但如果没有更高级的解析器来处理子字符串,您迟早会遇到麻烦。可能的麻烦包括混合引号和转义引号。此函数将按逗号拆分字符串,但不拆分单引号或双引号字符串中的逗号。它可以很容易地扩展额外的字符作为引号(尽管像« »这样的字符对需要多几行代码),甚至会告诉你是否忘记关闭数据中的引号:
function splitNotStrings(str){ var parse=[], inString=false, escape=0, end=0 for(var i=0, c; c=str[i]; i++){ // looping over the characters in str if(c==='\\'){ escape^=1; continue} // 1 when odd number of consecutive \ if(c===','){ if(!inString){ parse.push(str.slice(end, i)) end=i+1 } } else if(splitNotStrings.quotes.indexOf(c)>-1 && !escape){ if(c===inString) inString=false else if(!inString) inString=c } escape=0 } // now we finished parsing, strings should be closed if(inString) throw SyntaxError('expected matching '+inString) if(end<i) parse.push(str.slice(end, i)) return parse } splitNotStrings.quotes="'\"" // add other (symmetrical) quotes here
字符串
bfhwhh0e4#
试试这个正则表达式:
(?:"(?:[^\\"]+|\\(?:\\\\)*[\\"])*"|'(?:[^\\']+|\\(?:\\\\)*[\\'])*')\s*=>\s*(?:"(?:[^\\"]+|\\(?:\\\\)*[\\"])*"|'(?:[^\\']+|\\(?:\\\\)*[\\'])*')\s*,
字符串这也允许像“'foo\'bar' => 'bar\\',”这样的字符串。
'foo\'bar' => 'bar\\',
56lgkhnf5#
MarkusQ的回答对我来说很有效,大约一年,直到它没有。我刚刚得到一个堆栈溢出错误,一行大约有120个逗号和3682个字符。在Java中,像这样:
String[] cells = line.split("[\t,](?=(?:[^\"]|\"[^\"]*\")*$)", -1);
字符串下面是我的非常不优雅的替代品,它不会堆栈溢出:
private String[] extractCellsFromLine(String line) { List<String> cellList = new ArrayList<String>(); while (true) { String[] firstCellAndRest; if (line.startsWith("\"")) { firstCellAndRest = line.split("([\t,])(?=(?:[^\"]|\"[^\"]*\")*$)", 2); } else { firstCellAndRest = line.split("[\t,]", 2); } cellList.add(firstCellAndRest[0]); if (firstCellAndRest.length == 1) { break; } line = firstCellAndRest[1]; } return cellList.toArray(new String[cellList.size()]); }
型
baubqpgj6#
@SocialCensus,您在MarkusQ的评论中给出的示例(其中您添加了“与......并排“)与MarkusQ在上面给出的示例不兼容,如果我们将 sam 更改为 sam's :(test,a“逗号,",bob,“,sam's,",此处)与(,)(?=(?:[^"']|[”|'][^"']”)$).事实上,这个问题本身,“我并不真正关心单引号和双引号”,是模棱两可的。你必须弄清楚你用“或"来引用是什么意思。例如,是否允许嵌套?若有,有几个层次?如果只有1个嵌套级别,则内部嵌套引号之外但外部嵌套引号之内的逗号会发生什么情况?你还应该考虑到单引号本身是作为撇号出现的(例如,就像我前面用sam's给出的反例)。最后,您所创建的正则表达式并没有真正将单引号与双引号等同对待,因为它假定最后一种引号必须是双引号--并将最后一个双引号替换为['|“]也有一个问题,如果文本没有正确的引号(或如果使用了撇号),虽然,我想我们可能可以假设所有的引号都是正确的划定。MarkusQ的正则表达式回答了这个问题:找出所有后面有偶数个双引号的逗号(即在双引号外),并忽略所有后面有奇数个双引号的逗号(即在双引号内)。这通常与您可能需要的解决方案相同,但让我们来看看一些异常情况。首先,如果有人在结尾处留下了引号,那么这个正则表达式会找到所有错误的逗号,而不是找到所需的逗号或无法匹配任何逗号。当然,如果一个双引号丢失了,所有的赌注都没有了,因为可能不清楚丢失的双引号是属于结尾还是属于开头;然而,有一种情况是合法的,其中正则表达式可能会失败(这是第二个“异常”)。如果您调整正则表达式使其跨越文本行,则应注意,引用多个连续段落需要在每个段落的开头放置一个单双引号,并省略每个段落末尾的引号(最后一个段落末尾的引号除外)。这意味着在这些段落的空间上,正则表达式在某些地方失败,而在另一些地方成功。段落引用和嵌套引用的示例和简要讨论可以在http://en.wikipedia.org/wiki/Quotation_mark中找到。
6条答案
按热度按时间thigvfpy1#
这将匹配任何字符串,直到并包括第一个非引号“,”。这就是你想要的吗
字符串
如果你想要所有这些(作为一个反例,那个说这不可能的人),你可以写:
型
这将匹配所有这些。因此
型
用分号替换引号内的所有逗号 not,并生成:
型
如果你需要它跨换行符工作,只需添加m(多行)标志。
lg40wkob2#
下面的正则表达式将匹配双引号外的所有逗号,
字符串
DEMO
或(仅PCRE)
型
"[^"]*"
匹配所有双引号块。也就是说,在这个buz,"bar,foo"
输入中,这个正则表达式将只匹配"bar,foo"
。现在下面的(*SKIP)(*F)
使匹配失败。然后,它移动到|
符号旁边的模式,并尝试匹配剩余字符串中的字符。也就是说,在我们的输出中,|
旁边的,
将只匹配buz
后面的逗号。请注意,这不会匹配双引号内的逗号,因为我们已经跳过了双引号部分。DEMO的
下面的正则表达式将匹配双引号内的所有逗号,
型
DEMO的
g2ieeal73#
虽然可以使用正则表达式(我和其他人一样喜欢滥用正则表达式),但如果没有更高级的解析器来处理子字符串,您迟早会遇到麻烦。可能的麻烦包括混合引号和转义引号。
此函数将按逗号拆分字符串,但不拆分单引号或双引号字符串中的逗号。它可以很容易地扩展额外的字符作为引号(尽管像« »这样的字符对需要多几行代码),甚至会告诉你是否忘记关闭数据中的引号:
字符串
bfhwhh0e4#
试试这个正则表达式:
字符串
这也允许像“
'foo\'bar' => 'bar\\',
”这样的字符串。56lgkhnf5#
MarkusQ的回答对我来说很有效,大约一年,直到它没有。我刚刚得到一个堆栈溢出错误,一行大约有120个逗号和3682个字符。在Java中,像这样:
字符串
下面是我的非常不优雅的替代品,它不会堆栈溢出:
型
baubqpgj6#
@SocialCensus,您在MarkusQ的评论中给出的示例(其中您添加了“与......并排“)与MarkusQ在上面给出的示例不兼容,如果我们将 sam 更改为 sam's :(test,a“逗号,",bob,“,sam's,",此处)与(,)(?=(?:[^"']|[”|'][^"']”)$).事实上,这个问题本身,“我并不真正关心单引号和双引号”,是模棱两可的。你必须弄清楚你用“或"来引用是什么意思。例如,是否允许嵌套?若有,有几个层次?如果只有1个嵌套级别,则内部嵌套引号之外但外部嵌套引号之内的逗号会发生什么情况?你还应该考虑到单引号本身是作为撇号出现的(例如,就像我前面用sam's给出的反例)。最后,您所创建的正则表达式并没有真正将单引号与双引号等同对待,因为它假定最后一种引号必须是双引号--并将最后一个双引号替换为['|“]也有一个问题,如果文本没有正确的引号(或如果使用了撇号),虽然,我想我们可能可以假设所有的引号都是正确的划定。
MarkusQ的正则表达式回答了这个问题:找出所有后面有偶数个双引号的逗号(即在双引号外),并忽略所有后面有奇数个双引号的逗号(即在双引号内)。这通常与您可能需要的解决方案相同,但让我们来看看一些异常情况。首先,如果有人在结尾处留下了引号,那么这个正则表达式会找到所有错误的逗号,而不是找到所需的逗号或无法匹配任何逗号。当然,如果一个双引号丢失了,所有的赌注都没有了,因为可能不清楚丢失的双引号是属于结尾还是属于开头;然而,有一种情况是合法的,其中正则表达式可能会失败(这是第二个“异常”)。如果您调整正则表达式使其跨越文本行,则应注意,引用多个连续段落需要在每个段落的开头放置一个单双引号,并省略每个段落末尾的引号(最后一个段落末尾的引号除外)。这意味着在这些段落的空间上,正则表达式在某些地方失败,而在另一些地方成功。
段落引用和嵌套引用的示例和简要讨论可以在http://en.wikipedia.org/wiki/Quotation_mark中找到。