【问题标题】:Get numbers after a specific character C#获取特定字符 C# 之后的数字
【发布时间】:2021-11-23 05:15:48
【问题描述】:

我有一个包含此文本的字符串...

1. G66I11.J270.P5.C90.(+K2H1+)
2. G66I11.J90.P-5.(+K2H1+)
3. G66I215.4J270.P-55.Q-6.T2531(+K2H1+)
...

我需要提取字符“P”为5或55之后的值。

现在我使用 IndexOf 来获取:

int indexP = 0;
int number;
if (lines.Contains("P-"))
{
     indexP = lines.IndexOf("P-") + 1;
}
else if (lines.Contains("P") && !lines.Contains("P-"))
{
     indexP = lines.IndexOf("P");
}
if (lines.Contains("Q"))
{
    int indexQ = 0;
    if (lines.Contains(".Q"))
    {
         indexQ = lines.IndexOf(".Q");
    }

    if (indexQ > indexP)
    {
          number = Int.Parse(lines.Substring(indexP + 1, indexQ - indexP - 1));
    }
}

if (lines.Contains("C"))
{
    int indexC = 0;
    if (lines.Contains(".C"))
    {
         indexC = lines.IndexOf(".C");
    }

    if (indexC > indexP)
    {
          number = Int.Parse(lines.Substring(indexP + 1, indexC- indexP - 1));
    }
}
...

我完全返回,但“P”之后的字符可以是任何字符。

所以如果这样做的话,代码会很长:(

我想找到一条更短的路。你能告诉我怎么做吗? 谢谢。

【问题讨论】:

  • 您的示例中的预期结果是什么? 5、-5、-55?还是 5、5、55?可以有没有“P”的字符串吗?还是有多个“P”?还是“P”后面不跟数字?
  • @KlausGütter 的预期结果是 5、5、55。总是有“P”,在“P”之后总是有数字。不能有没有“P”的字符串或不能有多个“P”的字符串
  • 这不是对构成有效文本或无效文本的完整描述。我认为您的描述不足以告诉我如何验证任意字符串。我可以做出各种假设。看起来有由. 字符分隔的字段,例如 text.Split('.') 可能是一个好的开始。然后你可能想找到 StartsWith P 的子字符串。看起来.P-5. 应该提取-5.P5. 应该提取5。但我只是猜测。你应该在你的问题中澄清所有这些细节。 P3.14 是否应该返回 3.14
  • lines 应该是一个字符串数组还是包含换行符的单个字符串?我们应该先用换行符分割吗?
  • 抱歉没有具体说明。这是一个单独的行,而不是数组

标签: c# regex string


【解决方案1】:

您可以使用Regex 和匹配表达式。像这样的,

// Example input
List<string> input = new List<string>();
input.Add("G66I11.J270.P5.C90.(+K2H1+)");
input.Add("G66I11.J90.P-5.(+K2H1+)");
input.Add("G66I215.4J270.P-55.Q-6.T2531(+K2H1+)");
input.Add("G66I11.J90.X-5.(+K2H1+)");

Regex match = new Regex(@"(?<=P)-*\d+(?=.)");
var values = input.Select(x => match.Match(x)?.Value).Where(x => !string.IsNullOrEmpty(x)).ToList();

// values =
Count = 3
    [0]: "5"
    [1]: "-5"
    [2]: "-55"

Regex(@"(?&lt;=P)-*\d+(?=.)"); -> 从一开始就检查P .. 找到它之后,它需要0个或多个- .. 取数字(\d+)直到有一个.

唯一需要注意的是......它只选择第一个匹配项。如果您想要多个匹配项,请将match.Match 切换为match.Matches 方法,它会为您提供值列表。您必须更新 Select 语句以返回所有值。

【讨论】:

  • 但我想得到 Count = 3 [0]: "5" [1]: "5" [2]: "55" 我应该如何编辑正则表达式?
  • 有趣的是,在您的代码中您使用了 List 但在问题的代码中,它看起来像 lines 应该是一个字符串,带有 lines大概由换行符分隔。如果最初的问题对此更清楚,那就太棒了。
  • values.Count 会给你号码
  • "G98X30.Y292.5I87.75J18.5P5" 不匹配。我在你的正则表达式的最后添加 * 并且现在运行良好。谢谢
【解决方案2】:

您可以使用一个模式来匹配 P 后跟可选的 -,然后捕获一组中的数字 0-9。

P-?([0-9]+)
  • P-? 匹配 P 和可选的 -
  • ([0-9]+) 在第 1 组中捕获 1 个或多个数字 0-9

查看.NET regex demo(点击表格标签)C# demo

例如

string pattern = @"P-?([0-9]+)";
string s = @"1. G66I11.J270.P5.C90.(+K2H1+)
2. G66I11.J90.P-5.(+K2H1+)
3. G66I215.4J270.P-55.Q-6.T2531(+K2H1+)
G98X30.Y292.5I87.75J18.5P5K6";
var numbers = Regex.Matches(s, pattern)
           .Select(i => int.Parse(i.Groups[1].Value))
           .ToArray();
Console.WriteLine("[{0}]", string.Join(", ", numbers));

输出

[5, 5, 55, 5]

【讨论】:

  • 您的正则表达式与“G98X30.Y292.5I87.75J18.5P5K6”不匹配
  • @dev.for.live 我已经更新了答案,在这种情况下你不需要单词边界。
  • 是的,这就是我需要的。非常感谢 。我会把它作为答案
【解决方案3】:

试试这个 - 假设你的 'lines' 是一个像这样的多行字符串。

string lines = @"
1. G66I11.J270.P5.C90.(+K2H1+)
2. G66I11.J90.P-5.(+K2H1+)
3. G66I215.4J270.P-55.Q-6.T2531(+K2H1+)
";
Regex regex = new Regex(@"[^P]*P-?([^\.]+)\.");

var matches = regex.Matches(lines);
Console.WriteLine($"Count: {matches.Count}");
foreach (Match match in matches)
{
    Console.WriteLine($"{match.Groups[1].Value}");
}

// Count: 3
// 5
// 5
// 55

对于单行:

Regex regex = new Regex(@"[^P]*P-?([^\.]+)\.");

string line = "1. G66I11.J270.P5.C90.(+K2H1+)";
var match = regex.Match(line);
Console.WriteLine($"{match.Groups[1].Value}");
// 5

【讨论】:

  • 我刚刚在字符串上测试了它:G66I11.J270.P5.C90.(+K2H1+)。但是得到这个错误:prnt.sc/20lkx9u
  • 但是你没有使用我给你的代码(正则表达式字符串)。在您的图像中,它显示您正在为 RegEx 使用自己的无效字符串。
  • 但我需要每个单独的行的正则表达式。例如:正则表达式 regex = new Regex(@"[^P]*P-?([^\.]+)\."); Pnumber = regex.Match(lines[i]).Value;但我不擅长正则表达式来修复它们
  • 您也没有从匹配中获取正确的值。在这个答案中——你仍然需要得到.Groups[1].Value 而不仅仅是.Value
  • 我不知道如何解决它。我向你展示它是一个字符串。在您的示例中,您有 lines 并且它是一个字符串。我有lines,它是一个字符串。现在你想将lines 作为一个数组,将lines[i] 作为一个字符串?
猜你喜欢
  • 2019-02-12
  • 2019-04-22
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多