正则expression式来select引号之外的逗号
我不太确定这是否可能,所以我转向你。
我想find一个正则expression式来挑选所有不在报价集之外的逗号。
例如:
'foo' => 'bar', 'foofoo' => 'bar,bar'
这会在第一行挑出单个逗号,在'bar',
我并不关心单双引号。
有没有人有任何想法? 我觉得应该可以用readaheads,但是我的正则expression式太弱了。
这将匹配任何string,包括第一个不带引号的“,”。 那是你想要的吗?
/^([^"]|"[^"]*")*?(,)/
如果你想要所有这些东西(作为一个说不可能的人的反例),你可以写:
/(,)(?=(?:[^"]|"[^"]*")*$)/
这将匹配所有的人。 从而
'test, a "comma,", bob, ",sam,",here'.gsub(/(,)(?=(?:[^"]|"[^"]*")*$)/,';')
用分号replace引号内的所有逗号,并产生:
'test; a "comma,"; bob; ",sam,";here'
如果你需要它跨线换行,只需添加m(多行)标志。
下面的正则expression式可以匹配所有在双引号之外的逗号,
,(?=(?:[^"]*"[^"]*")*[^"]*$)
DEMO
或 (仅限PCRE)
"[^"]*"(*SKIP)(*F)|,
这个正则expression式只匹配"bar,foo"
现在下面的(*SKIP)(*F)
使匹配失败,然后移动到符号旁边的模式,并尝试匹配剩余string中的字符,也就是说,在我们的输出中,
模式|
旁边将只匹配刚才的逗号请注意,这与双引号内的逗号不匹配,因为我们已经使双引号部分跳过了。
DEMO
下面的正则expression式可以匹配双引号内的所有逗号,
,(?!(?:[^"]*"[^"]*")*[^"]*$)
DEMO
@SocialCensus,你在MarkusQ的评论中给出的例子,你在'旁边'扔',不符合MarkusQ给出的例子,如果我们把sam改成sam :(test,“comma” bob,“sam's”,这里)没有匹配(,)(?=(?:[^“'] | [”|'] [^“'] ”) $)。 ,“我真的不在乎单引号还是双引号”,是不明确的,你必须用“或with”来引出你的意思。 例如,嵌套是否允许? 如果是的话,多less级别? 如果只有一个嵌套级别,那么内部嵌套引号之外的逗号会发生什么变化,而外部嵌套引号之内呢? 你也应该认为单引号本身就是撇号(就像我之前给出的反例)。 最后,你所做的正则expression式并不真正把单引号与双引号相提并论,因为它假定最后一种引号是双引号,并且用['|“]代替最后一个双引号也有问题如果文本没有带正确的引号(或者使用了撇号),我想我们可能会假设所有的引号都被正确地描述了。
MarkusQ的正则expression式回答了这个问题:find所有在双引号之后有双引号(即在双引号之外)的逗号,而忽略所有在双引号之后有双引号的逗号(即双引号内)。 这通常与您可能想要的解决scheme相同,但是我们来看一些exception情况。 首先,如果有人在最后留下一个引号,那么这个正则expression式会find所有错误的逗号,而不是find所需的或不匹配的。 当然,如果缺less一个双引号,所有的投注都是closures的,因为可能不清楚这个缺失的属于最后还是属于开始。 然而,有一个合法的情况,正则expression式可能会失败(这是第二个“exception”)。 如果您调整正则expression式以跨越文本行,那么您应该意识到,引用多个连续段落要求在每个段落的开始处放置一个双引号,并在每段的结尾处省略引号最后一段的结尾。 这意味着,在这些段落的空间中,正则expression式在某些地方会失败,并在其他地方成功。
段落引用和嵌套引用的示例和简要讨论可以在这里findhttp://en.wikipedia.org/wiki/Quotation_mark 。
虽然有可能用正则expression式来攻击它(我喜欢和下一个人一样滥用正则expression式),但是如果没有更高级的parsing器,迟早你会遇到麻烦。 可能的麻烦方式包括混合引号和逃脱引号。
该函数将以逗号分割一个string,而不是在单引号或双引号string中的逗号。 它可以很容易地扩展与额外的字符用作引号(虽然字符对像«»将需要更多的代码行),甚至会告诉你,如果你忘记closures在你的数据报价:
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
试试这个正则expression式:
(?:"(?:[^\\"]+|\\(?:\\\\)*[\\"])*"|'(?:[^\\']+|\\(?:\\\\)*[\\'])*')\s*=>\s*(?:"(?:[^\\"]+|\\(?:\\\\)*[\\"])*"|'(?:[^\\']+|\\(?:\\\\)*[\\'])*')\s*,
这也允许string像'foo\'bar' => 'bar\\',
“。
MarkusQ的答案对我来说工作了一年,直到没有。 我只是在一个大约有120个逗号和3682个字符的行上出现堆栈溢出错误。 在Java中,像这样:
String[] cells = line.split("[\t,](?=(?:[^\"]|\"[^\"]*\")*$)", -1);
这是我非常不雅的replace,不堆栈溢出:
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()]); }