[英]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 + =“(\\ 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.