C# 从字符串中获取特定部分
我试图从字符串中获取特定部分。我必须得到以@开头的部分,它只包含拉丁字母表中的字母 我想我必须创建一个正则表达式模式,但我不知道如何创建C# 从字符串中获取特定部分,c#,regex,C#,Regex,我试图从字符串中获取特定部分。我必须得到以@开头的部分,它只包含拉丁字母表中的字母 我想我必须创建一个正则表达式模式,但我不知道如何创建 string test = "PQ@Alderaa1:30000!A!->20000"; var planet = "Alderaa"; //what I want to get string test2 = "@Cantonica:3000!D!->4000NM"; var planet2 = "Cantonica"; 还有一些其他的部分,我必
string test = "PQ@Alderaa1:30000!A!->20000";
var planet = "Alderaa"; //what I want to get
string test2 = "@Cantonica:3000!D!->4000NM";
var planet2 = "Cantonica";
还有一些其他的部分,我必须得到,但我会尽量让他们自己。(在“:”之后开始,是一个整数;可能是“A”(攻击)或“D”(销毁),必须用“!”(感叹号)包围;在“->”之后开始,应该是一个整数)您可以使用这个正则表达式,它使用正向查找来确保匹配的文本前面有
@
并且使用捕获一个或多个字母表[a-zA-Z]+
并使用积极的前瞻性,以确保它后面紧跟一些可选文本、冒号、一个或多个数字,然后紧跟!
,然后是a
或D
,然后是!
(?<=@)[a-zA-Z]+(?=[^:]*:\d+![AD]!)
您可以使用捕获组获取单独的部分:
@([a-zA-Z]+)[^:]*:(\d+)!([AD])!->(\d+)
这将符合:
匹配@([a-zA-Z]+)
并在第1组中捕获1+次a-zA-Z@
使用一个否定的数字匹配0+次非a[^::*:
,然后匹配a:
(如果下面的数字只能是可选数字,您也可以匹配0+次数字:
)[0-9]*
- (\d+)在第2组中捕获1+个数字
Match!,在第3组和A或D组中捕获,然后匹配!([AD])!
匹配->(\d+)
并捕获第4组1+位数字->
|您已经有了一个很好的答案,但我想添加一个新答案来显示命名的捕获组 你可以为你的行星创建一个类,比如
class Planet
{
public string Name;
public int Value1; // name is not cleat from context
public string Category; // as above: rename it
public string Value2; // same problem
}
现在,您可以将正则表达式与命名组一起使用
@(?<name>[a-z]+)[^:]*:(?<value1>\d+)!(?<category>[^!]+)!->(?<value2>[\da-z]+)
@(?[a-z]+)[^::*:(?\d+)(?[^!]+)!->(?[\da-z]+)
用法:
var input = new[]
{
"PQ@Alderaa1:30000!A!->20000",
"@Cantonica:3000!D!->4000NM",
};
var regex = new Regex("@(?<name>[a-z]+)[^:]*:(?<value1>\\d+)!(?<category>[^!]+)!->(?<value2>[\\da-z]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
var planets = input
.Select(p => regex.Match(p))
.Select(m => new Planet
{
Name = m.Groups["name"].Value, // here and further we can access to part of input string by name
Value1 = int.Parse(m.Groups["value1"].Value),
Category = m.Groups["category"].Value,
Value2 = m.Groups["value2"].Value
})
.ToList();
var输入=新[]
{
"PQ@Alderaa1:30000!A!->20000“,
“@Cantonica:3000!D!->4000NM”,
};
var regex=new regex(“@(?[a-z]+)[^::*:(?\\d+)(?[^!]+)!->(?[\\da-z]+)”,
RegexOptions.IgnoreCase | RegexOptions.Compiled);
变量=输入
.Select(p=>regex.Match(p))
.选择(m=>new Planet
{
Name=m.Groups[“Name”].Value,//我们可以通过名称访问输入字符串的一部分
Value1=int.Parse(m.Groups[“Value1”].Value),
类别=m.组[“类别”]值,
Value2=m.Groups[“Value2”].值
})
.ToList();
wauw这很有趣,我从来没有真正研究过正则表达式模式,我只是简单地进行了分解等等。这是如何工作的?这会返回一个带有结果的数组吗?@Livo获取捕获组的一种方法是这样的,使用“谢谢”,这对我非常有帮助!@Thefourthbird,谢谢你的回答!我正在测试正则表达式,但是为什么它不匹配整个单词,只匹配“Cantonic”。@啊,我明白了,我已经更新了它@([a-zA-Z]+)[^::*:(\d+)([AD])!->(\d+)
可能是个愚蠢的问题,但是“p”在代码段中做了什么,它在哪里声明,或者像for循环,在内部声明?@Livop
是一个lambda参数,它声明为“inline”。您可以重命名它以实现planet=>regex.Match(planet)
它仍然可以工作。与m
参数相同哦,所以你把每个输入都放在一个p中,这似乎是每个的某种形式,然后用p为每个选择一个新的m,并定义行星,其中p只是正则表达式匹配的地方,m是值:D。谢谢!我发现这是构建和测试正则表达式的一个很好的资源。
@(?<name>[a-z]+)[^:]*:(?<value1>\d+)!(?<category>[^!]+)!->(?<value2>[\da-z]+)
var input = new[]
{
"PQ@Alderaa1:30000!A!->20000",
"@Cantonica:3000!D!->4000NM",
};
var regex = new Regex("@(?<name>[a-z]+)[^:]*:(?<value1>\\d+)!(?<category>[^!]+)!->(?<value2>[\\da-z]+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
var planets = input
.Select(p => regex.Match(p))
.Select(m => new Planet
{
Name = m.Groups["name"].Value, // here and further we can access to part of input string by name
Value1 = int.Parse(m.Groups["value1"].Value),
Category = m.Groups["category"].Value,
Value2 = m.Groups["value2"].Value
})
.ToList();