不,但如果您在此解决方案中创建一个扩展方法,则可以使用 state machine 且不使用正则表达式。
在不了解所有限制条件的情况下,这可能不是 100% 正确,但它确实产生了您正在寻找的正确输出。如有必要,您可以为此添加状态和约束。
class Program
{
static void Main(string[] args)
{
var input = @" {..}P1, {.sdfsdfsdf.}P2, {.sdfsdfsdf.}P3, {..}P3
{..}P4, {..}P1, {..}P8886, {..}P5";
var items = Extractinator(input).Distinct().OrderBy(x => x).ToList();
Console.WriteLine(string.Join(", ", items));
Console.ReadLine();
}
static IEnumerable<string> Extractinator(string source)
{
var state = States.Extraneous;
string item = "";
foreach (var c in source)
{
switch (state)
{
case States.Extraneous:
switch (c)
{
case '{':
state = States.InsideBrackets;
break;
}
continue;
case States.InsideBrackets:
switch (c)
{
case '}':
state = States.BuildingItem;
break;
}
continue;
case States.BuildingItem:
switch (c)
{
case char _ when char.IsDigit(c) || char.IsLetter(c):
item += c;
break;
default:
yield return item;
item = "";
state = States.Extraneous;
break;
}
continue;
}
}
if (item != "")
yield return item;
}
enum States
{
Extraneous,
InsideBrackets,
BuildingItem,
}
}
我修改了输入只是为了让它更真实一点。我还使用了switch 而不是if/else,因为这是一种“经典”方式,允许您在必要时添加新规则。例如,如果逗号, 确实是移动到无关文本的信号,那么在case States.BuildingItem 中,您可能希望将case char _ when char.IsDigit(c) || char.IsLetter(c): 替换为case char _ when c != ',':。
像这样的状态机的关键是缓冲部分结果,在完成时产生/处理结果,并知道何时切换状态。