【问题标题】:Get sub-strings from a string that are enclosed using some specified character从使用某些指定字符括起来的字符串中获取子字符串
【发布时间】:2023-03-19 14:50:01
【问题描述】:

假设我有一个字符串

喜欢 (20)

我想从这个字符串中获取用圆括号括起来的子字符串(在上面的例子中是 20)。此子字符串可以在运行时动态更改。它可能是从 0 到无穷大的任何其他数字。为了实现这一点,我的想法是使用遍历整个字符串的for 循环,然后当存在( 时,它开始将字符添加到另一个字符数组中,当遇到) 时,它会停止添加字符并返回数组。但我认为这可能表现不佳。我对正则表达式知之甚少,那么有没有可用的正则表达式解决方案或任何函数可以有效地做到这一点?

【问题讨论】:

  • string num = Regex.Match("Likes (20)", @"\d+").Value;
  • "但包含的字符串可能会动态变化。" - 这在你的问题中没有说明......更具体,给出更多例子等等等等,即付出一些努力
  • lol erm 不,假设你有一个字符串“345”,假设它是空的,假设它是空的,假设它是“(20)(30)”,这是很多假设......会不会杀了你更具体?
  • 你能详细说明一下Enclosed string might change dynamically吗?
  • @AishwaryaShiva 数字可以改变的事实很好!只要字符串的其余部分保持静态,例如Likes (2000000) 包括我自己在内的许多解决方案都非常适合您。

标签: c# .net regex string substring


【解决方案1】:

当括号中的部分应该是数字时匹配;

string inputstring="Likes (20)"
Regex reg=new Regex(@"\((\d+)\)")
string num= reg.Match(inputstring).Groups[1].Value

说明: 根据定义,正则表达式匹配子字符串,因此除非您另有说明,否则您要查找的字符串可以出现在字符串中的任何位置。

\d 代表数字。它将匹配任何单个数字。

我们希望它可能会重复多次,并且我们希望至少有一次。 + 号是​​前一个符号或组重复 1 次或多次的正则表达式。

所以 \d+ 将匹配一个或多个数字。它将匹配 20。

为了确保我们得到 paranteses 中的数字,我们说它应该在 ( 和 ) 之间。这些是正则表达式中的特殊字符,因此我们需要对它们进行转义。

(\d+) 将匹配 (20),我们就快到了。

由于我们想要括号内的部分,而不包括括号,我们告诉正则表达式数字部分是一个单独的组。

我们通过在正则表达式中使用括号来做到这一点。 ((\d+)) 仍然会匹配 (20),但现在它会注意到 20 是该匹配的子组,我们可以通过 Match.Groups[] 获取它。

对于括号中的任何字符串,事情都会变得有点困难。

Regex reg=new Regex(@"\((.+)\)")

适用于许多字符串。 (点匹配任何字符)但如果输入类似于“这是一个示例(parantesis1)(parantesis2)”,您将匹配 (parantesis1)(parantesis2) 与 parantesis1)(parantesis2 作为捕获的子组。这不太可能做你所追求的。

解决方案可以是对“除右括号外的任何字符”进行匹配

Regex reg=new Regex(@"\(([^\(]+)\)")

这将找到 (parantesis1) 作为第一个匹配项,其中 parantesis1 为 .Groups[1]。

嵌套括号仍然会失败,但是由于正则表达式不是嵌套括号的正确工具,我觉得这种情况有点超出范围。

如果您知道字符串总是在组之前以“喜欢”开头,那么保存解决方案会更好。

【讨论】:

    【解决方案2】:

    如果你不喜欢使用正则表达式,你可以使用Split:

    string foo = "Likes (20)";
    string[] arr = foo.Split(new char[]{ '(', ')' }, StringSplitOptions.None);
    string count = arr[1];
    

    Count = 20

    无论括号中的数字是多少()

    ,这都能正常工作

    例如:

    喜欢 (242535345)

    将给予:

    242535345

    【讨论】:

    • 这对良好的格式做了很多假设。 ")start(123)" 给出开始。
    • OP 已经声明字符串的其余部分保持静态 - yup, the rest of the string will remain static。在字符串完全损坏的情况下,例如 )start(123) 我会说 OP 手上有更大的问题......
    • 不,我只需要数字。正如我在问题The substring will be a number from 0 to infinity 中所说。
    • 感谢@DGibbs 和所有回答并回答我问题的人 :)
    • @AishwaryaShiva 乐于助人
    【解决方案3】:
    const string likes = "Likes (20)";
    int likesCount = int.Parse(likes.Substring(likes.IndexOf('(') + 1, (likes.Length - likes.IndexOf(')') + 1 )));
    

    【讨论】:

    • 让我列出这个答案的错误之处:1.) string 不包含方法 substring,也不包含方法 indexOf2.) C# 是区分大小写的语言。 3.) 您缺少 ) 括号 4.) 您缺少分号 ; 5.) 当上述问题已得到纠正,这甚至没有返回正确的结果 - 它给出了 2 而不是 20。 -1
    • 您仍然缺少 )
    【解决方案4】:

    即使使用 Linq:

    var s = "Likes (20)";
    var s1 = new string(s.SkipWhile(x => x != '(').Skip(1).TakeWhile(x => x != ')').ToArray());
    

    【讨论】:

    • 比纯字符串方法效率低得多,可读性也差很多。
    • 当然,这只是另一种方法。
    【解决方案5】:

    对于严格匹配,你可以这样做:

    Regex reg = new Regex(@"^Likes\((\d+)\)$");
    Match m = reg.Match(yourstring);
    

    这样您就可以在m.Groups[1].Value 中获得所需的一切。

    根据 I4V 的建议,假设您在整个字符串中只有该数字序列,如您的示例所示,您可以使用更简单的版本:

    var res = Regex.Match(str,@"\d+")
    

    在这个罐子里,你可以通过res.Value得到你正在寻找的价值

    编辑

    如果括号中的值不只是数字,如果您想在其中允许字母字符、数字和空格,您可以将 \d 更改为 [\w\d\s] 之类的内容。

    【讨论】:

      【解决方案6】:

      也适用于纯字符串方法:

      string result = "Likes (20)";
      int index = result.IndexOf('(');
      if (index >= 0)
      {
          result = result.Substring(index + 1); // take part behind (
          index = result.IndexOf(')');
          if (index >= 0)
              result = result.Remove(index);    // remove part from )
      }
      

      Demo

      【讨论】:

      • @PaulZahra:指定“不起作用”。结果20 有什么问题?在哪里指定这是可能的并且他想要提取所有值而不仅仅是第一个值?
      • 它将如何处理“(1(2)3)”?
      • @Taemyr:它将返回1(2。我从来没有说过每个输入都是安全的。它需要严格的模式(类似于正则表达式)。但是,如果我只能使用字符串方法来做事,我会使用它们,因为它们更高效、更易读(对很多人来说)并且它们允许在内部添加额外的逻辑(比如日志记录)。
      • 我只是强调一个事实,即他在原始未编辑的问题中并不具体,他实际上“假设”该字符串将是 Like (20)... 非常模棱两可,尽管他现在已经在他的编辑中更具体。
      • 可悲的是,人们并不倾向于遵守 SO 规则,他们随心所欲地投票。恕我直言,这很有帮助,所以我给它 +1 以对抗愚蠢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      • 2022-01-18
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多