tyr*_*ron 9 c# regex split tokenize
我有一些"标记化"模板,例如(我称之为双括号之间的标记):
var template1 = "{{TOKEN1}} is a {{TOKEN2}} and it has some {{TOKEN3}}";
Run Code Online (Sandbox Code Playgroud)
我想从这句话中提取一个数组,以便有类似的东西:
Array("{{TOKEN1}}",
" is a ",
"{{TOKEN2}}",
" and it has some ",
"{{TOKEN3}}");
Run Code Online (Sandbox Code Playgroud)
我已尝试使用以下Regex代码实现此目的:
Regex r = new Regex(@"({{[^\}]*}})");
var n = r.Split(template1);
Run Code Online (Sandbox Code Playgroud)
结果是:
Array("",
"{{TOKEN1}}",
" is a ",
"{{TOKEN2}}",
" and it has some ",
"{{TOKEN3}}",
"");
Run Code Online (Sandbox Code Playgroud)
第一个问题是我无法从句子中恢复令牌.我只是通过在Regex表达式上添加括号来解决这个问题,即使我不确定为什么它会解决这个问题.
我目前面临的问题是当模板上的第一个和/或最后一个术语是"标记"时,数组开头和/或结尾的额外空术语.为什么会这样?我做错了什么,或者我应该经常检查这两个位置是否空虚?
在我的代码中,我需要知道哪个术语来自一个令牌,哪个是模板上的固定位置.在这个解决方案中,我将检查每个数组的位置,以"{{"和"}}"开头的字符串,我不认为这是最好的可能性.所以,如果有人想出一个更好的解决方案来打破这些事情,我会很高兴知道!
谢谢!
编辑:根据要求,我将发布一个简单的例子,为什么我需要对令牌和文本进行区分.
public abstract class TextParts { }
public class TextToken : TextParts { }
public class TextConstant : TextParts { }
var list = new List<TextParts>();
list.Add( new TextToken("{{TOKEN1}}") );
list.Add( new TextConstant(" is a ") );
list.Add( new TextToken("{{TOKEN2}}") );
/* and so on */
Run Code Online (Sandbox Code Playgroud)
这样,我将有一个组成我的字符串的部分列表,我将能够在我的数据库上记录它,以便将来操作和替换.实际上,每个TOKEN都将被Regex字符串取代.
目标是用户可以输入"{{SERVER}}没有侦听端口{{PORT}}"之类的消息,并且我将能够将"{{SERVER}}"替换为[a-zA-Z0-9 ]+"{{ PORT}}"来\d{1,5}.说得通?
我希望这会使帖子更加清晰.
如果沿分隔符拆分字符串,并且字符串以分隔符开头或结尾,则表示在第一个/最后一个分隔符之前/之后有一个空元素:
想象一下CSV文件中的以下行:
,a,b,c,
Run Code Online (Sandbox Code Playgroud)
这CSV行中包含的元素"","a","b","c",和"".
同样的事情发生在你的身上{{TOKEN}}.您可以使用其他方法:
MatchCollection allMatchResults = null;
Regex regexObj = new Regex(@"\{\{[^{}]*\}\}|[^{}]+");
allMatchResults = regexObj.Matches(subjectString);
Run Code Online (Sandbox Code Playgroud)
如果在标记内或标记之间可能出现单个括号,您也可以使用
Regex regexObj = new Regex(@"\{\{(?:(?!\}\}).)*\}\}|(?:(?!\{\{).)+");
Run Code Online (Sandbox Code Playgroud)
但是,由于所有前瞻性断言,效率会低一些,所以只有在需要时才应该使用它.
编辑:我刚注意到你的帖子中还有另一个问题:为什么你需要在正则表达式周围添加括号以使其"正常"?答:通常,split()命令只返回 分隔符之间的内容.如果将分隔符(或其中的一部分)括在捕获括号中,则这些括号内匹配的内容也将添加到结果列表中.