繁体   English   中英

正则表达式怪异的行为,无法满足我的需求

[英]Regex weird behavior, won't match what I need

我有三个不同的输入。

<inverse content="HelloWorlD"/>
<reverse content="helloworld"/>
<repeat value="2" content="helloworld"/>

在第一个输入中,我需要反转内容中字符串中的字符。

关于第二个,我需要做同样的事情,但是要扭转它们。

在第三个值中,当X是值数字时,我需要重复内容X中的字符串数。

我正在使用正则表达式来匹配输入。

它完美地匹配了所有内容。

在此处输入图片说明

它非常适合反向命令和反向命令,但是当我尝试匹配重复行时,会将它们置于两个不同的匹配项中,这对我不起作用。

在此处输入图片说明

string line = Console.ReadLine();
Regex pattern = new Regex("(\\w+) \\w+=\"(\\w+)\"| \\w+=\"(\\w+)\"");

List<string> list = new List<string>();

while (line != "stop")
{
    MatchCollection matcher = pattern.Matches(line);

    foreach (Match match in matcher)
    {
        string command = match.Groups[1].ToString();
        string content;
        int value;

        switch (command)
        {
            case "inverse":
                content = match.Groups[2].ToString();
                list.Add(InverseContent(content));
                break;
            case "reverse":
                content = match.Groups[2].ToString();
                list.Add(ReverseContent(content));
                break;
            case "repeat":
                value = int.Parse(match.Groups[2].ToString());
                content = match.Groups[3].Value;
                for (int i = 0; i < value; i++)
                {
                    list.Add(content);
                }
                break;
        }
    }
    line = Console.ReadLine();
}

使用?将第二个值设为可选

"(\\w+) \\w+=\"(\\w+)\"(\\s+\\w+=\"(\\w+)\")?"

对于“重复”情况,它将产生组#2和#4中的值。

在此处输入图片说明

试试这个正则表达式:

(\\ w +)\\ w + =“(\\ d +){0,1}” \\ w + =“(\\ w +)”

这可能是多余的,但是我还是要发布它。

由于您的数据看起来是格式正确的XML-我们可以使用XML解析器来获取结构化的命令列表。 这将使您的解决方案更易于测试,并能够处理更复杂的情况。 它将处理诸如<inverse content="HelloWorld"></inverse>形式以及重新排列属性<repeat content="x" value="3" />而不是<repeat value="3" content="x" /> 它还可以支持值内的任何随机输入(不仅限于单词字符)。

如果您的输入被根元素包围(如果您不这样输入,则可以插入自己)-输入是格式正确的xml。 例:

//file: input.xml
<input>
  <inverse content="HelloWorld" />
  <reverse content="helloworld" />
  <repeat value="2" content="helloworld" />
</input>

然后,我们可以构造一个类来表示您的输入命令列表,如下所示:

[XmlRoot("input")] //indicate that this class represents the xml file
public class CommandList
{   
    // tell the XmlSerializer which <element> belongs to which class.
    [XmlElement("repeat", typeof(Repeat))]
    [XmlElement("reverse", typeof(Reverse))]
    [XmlElement("inverse", typeof(Inverse))]
    public List<Command> Commands { get; } = new List<Command>();
}

Command类是abstract ,具有三个不同的实现,具体取决于元素:

public abstract class Command
{
    [XmlAttribute("content")]
    public string Content { get; set; }
    public abstract void Process(List<string> output);
}

定义抽象类之后,我们可以将不同的命令创建为单独的类:

public class Inverse : Command
{
    public override void Process(List<string> output)
    {
        var inverseContent = this.Content; //todo: process
        output.Add(inverseContent);
    }
}
public class Reverse : Command
{
    public override void Process(List<string> output)
    {
        var reverseContent = this.Content; //todo: process
        output.Add(reverseContent);
    }
}

对于Repeat类,有一个额外的属性,即value

public class Repeat : Command
{
    [XmlAttribute("value")]
    public int Value { get; set; }
    public override void Process(List<string> output)
    {
        for (int i = 0; i < this.Value; i++)
        {
            output.Add(this.Content);
        }
    }
}

然后,运行您的解决方案:

using System.IO;
using System.Xml.Serialization;

var serializer = new XmlSerializer(typeof(CommandList));
var result = (CommandList)serializer.Deserialize(File.OpenRead("input.xml"));
var output = new List<string>();
foreach (var command in result.Commands)
{
    command.Process(output);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM