我有以下输入字符串:
key1 = "test string1" ; key2 = "test string 2"
我需要将其转换为以下内容而不进行标记化
key1="test string1";key2="test string 2"
答案 0 :(得分:5)
你最好不要使用正则表达式。
你应该做的是解析字符串。你所描述的问题是一种迷你语言,因为该字符串中的每个点都有一个状态(例如“在引用的字符串中”,“在关键部分”,“赋值”)。
例如,当您决定要转义字符时会发生什么?
key1="this is a \"quoted\" string"
逐个字符串移动字符串,随时保持和更改状态。根据状态,您可以发出或省略您刚读过的字符。
作为奖励,您将能够检测语法错误。
答案 1 :(得分:2)
使用ERE,即扩展正则表达式(在这种情况下比基本RE更清晰),假设没有引用转义并具有全局标志(以替换所有出现),您可以这样做:
s/ *([^ "]*) *("[^"]*")?/\1\2/g
sed的:
$ echo 'key1 = "test string1" ; key2 = "test string 2"' | sed -r 's/ *([^ "]*) *("[^"]*")/\1\2/g'
C#代码:
using System.Text.RegularExpressions;
Regex regex = new Regex(" *([^ \"]*) *(\"[^\"]*\")?");
String input = "key1 = \"test string1\" ; key2 = \"test string 2\"";
String output = regex.Replace(input, "$1$2");
Console.WriteLine(output);
输出:
key1="test string1";key2="test string 2"
Escape-aware version
第二个想法我得出的结论是,没有显示regexp的逃避感知版本可能会导致错误的发现,所以这里是:
s/ *([^ "]*) *("([^\\"]|\\.)*")?/\1\2/g
在C#中看起来像:
Regex regex = new Regex(" *([^ \"]*) *(\"(?:[^\\\\\"]|\\\\.)*\")?");
String output = regex.Replace(input, "$1$2");
请不要因为那些反斜杠而失明!
实施例
Input: key1 = "test \\ " " string1" ; key2 = "test \" string 2"
Output: key1="test \\ "" string1";key2="test \" string 2"