我的问题很复杂,但可以归结为一个简单的例子.
我正在编写一种自定义查询语言,用户可以在其中输入我解析为LinQ Expressions的字符串.
我想要做的是按*字符分割字符串,除非它被正确转义.
Input Output Query Description
"*\\*" --> { "*", "\\", "*" } -- contains a '\'
"*\\\**" --> { "*", "\\\*", "*" } -- contains '\*'
"*\**" --> { "*", "\*", "*" } -- contains '*' (works now)
Run Code Online (Sandbox Code Playgroud)
我不介意Regex.Split返回空字符串,但我最终得到了这个:
Regex.Split(@"*\\*", @"(?<!\\)(\*)") --> {"", "*", "\\*"}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我尝试过负面的lookbehind,它适用于我的所有情况,除了这个.我也试过了Regex.Escape,但没有运气.
显然,我的问题是我在找\*,哪个\\*匹配.但在这种情况下,
\\是另一个转义序列.
任何解决方案都不一定要涉及正则表达式.
我认为匹配要比拆分容易得多,特别是因为你没有从初始字符串中删除任何东西.那么匹配什么?除了未转义之外的一切*.
怎么做?使用以下正则表达式:
@"(?:[^*\\]+|\\.)+|\*"
Run Code Online (Sandbox Code Playgroud)
(?:[^*\\]+|\\.)+匹配不是a *或任何转义字符的所有内容.无需任何外观.
\* 将匹配分隔符.
在代码中:
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Test
{
public static void Main()
{
string[] tests = new string[]{
@"*\\*",
@"*\\\**",
@"*\**",
};
Regex re = new Regex(@"(?:[^*\\]+|\\.)+|\*");
foreach (string s in tests) {
var parts = re.Matches(s)
.OfType<Match>()
.Select(m => m.Value)
.ToList();
Console.WriteLine(string.Join(", ", parts.ToArray()));
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
*, \\, *
*, \\\*, *
*, \*, *
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2625 次 |
| 最近记录: |