我想用以下字符串做的是用制表替换所有的“comas”,除非所说的昏迷在大括号{}之间。
说我有:
goldRigged,1,0,0,0,1,0,0,0,1,"{"LootItemID": "goldOre", "Amount": 1}"
结果应为:
goldRigged\t1\t0\t0\t0\t1\t0\t0\t0\t1\t"{"LootItemID": "goldOre"**,** "Amount": 1}"
我已经\"(\\{((.*?))\\})\"
允许我匹配{ }
之间的内容。
我们的想法是用某些内容排除内容,并使用类似\",^(\\{((.*?))\\})\"
之类的内容匹配任何内容。
但我想通过这样做会排除逗号本身。
答案 0 :(得分:1)
你需要的是一种负向前瞻和负面的后视。但是,这将构成一个非常复杂的陈述:
匹配所有前面没有开括号的逗号,只要它们之前没有前面的括号(加上逗号右侧的恢复逻辑)。这将导致表达式难以处理,因为正则表达式引擎不断需要从当前位置向上和向下运行字符串,效率相当低。
相反,迭代字符串的所有字符。如果匹配左大括号,请设置转义提示。当你找到一个闭合支撑时,将其移除。当您找到逗号时,请在未设置转义提示时替换它。将结果写入某种字符串缓冲区,您的解决方案将比正则表达式更有效率。
答案 1 :(得分:1)
您希望使用否定的外观来实现此目的:
(?<![\{\}]),*(?![\{\}])
应该有效,请点击此处:http://regex101.com/r/gG3oU1
答案 2 :(得分:1)
在正则表达式中使用否定前瞻(?!expr)
和否定后瞻(?<!expr)
例如,您可以像这样编码:
System.Text.RegularExpressions.Regex.Replace(
"goldRigged,1,0,0,0,1,0,0,0,1, {\"LootItemID\": \"goldOre\", \"Amount\": 1}" ,
@"(?<!\{[^\}].*)[,](?![^\{]*\})", "\t");
答案 3 :(得分:0)
您的输入行是否包含{仅在最后一个令牌中? 如果是,那么你可以尝试这种蛮力方法
echo "goldRigged,1,0,0,0,1,0,0,0,1,"{"LootItemID": "goldOre", "Amount": 1}"" | awk -F'{' '{one=$1;gsub(",","\t",one);printf("%s{%s\n",one,$2);}
答案 4 :(得分:0)
以下正则表达式是一种昂贵的方式。根据@Sniffer的建议,解析器在这里会更好:)
(?=,.*?"{),|(?!,.*?\}),
第一次轮换
(?=,.*?"{),
- 确保逗号位于序列"{
第二次轮换
(?!,.*?\}),
- 确保逗号不在序列}"
将会有一些尚未考虑的边缘情况,即解析器进入
答案 5 :(得分:0)
我认为你实际上只需要一个前瞻:
,(?=[^{}]*({|$))
读取:逗号,然后是一些非括号,然后是一个开括号或结束。
JS中的示例:
> x = 'goldRigged,1,0,0,0,1,0,0,0,1,"{"LootItemID": "goldOre", "Amount": 1}",some,more{stuff,ff}end'
> x.replace(/,(?=[^{}]*({|$))/g, "@")
"goldRigged@1@0@0@0@1@0@0@0@1@"{"LootItemID": "goldOre", "Amount": 1}"@some@more{stuff,ff}end"
注意如果可以嵌套大括号,这不起作用,在这种情况下,您需要一个带递归(?R
)的正则表达式引擎或正确的解析器。