【问题标题】:C# search for specific string with specific lengthC#搜索具有特定长度的特定字符串
【发布时间】:2015-11-18 21:58:59
【问题描述】:

我有一个巨大的 xml,我应该在其中搜索特定的字符串。

字符串长度必须为 13 个字母,并且必须全部为数字。

我相信使用正则表达式适合此类应用,但我对正则表达式的了解有限,因此任何类型的示例都会很有用。

还有哪些其他方法可以用于此类字符串搜索应用程序。

  <field name="TKT">
    <item>
      <index>1</index> 
        <text>Y24AUGXLOWS 2352159617737</text> 
    </item>
  </field>
  <field name="AP FAX">
    <item>
      <index>1</index> 
        <text>1 S1 SSRTKNETKHK1 2352159617737C1</text> 
    </item>
  </field>

这是我正在谈论的部分 xml 示例。例如我想提取数字“2352159617737”。

谢谢。

【问题讨论】:

  • 你能提供一个xml的例子吗?是您要查找的特定单词,还是包含 13 个字符的元素?
  • 在“c# regex guide”上快速谷歌搜索导致this site,其中有一个查找数字字符串的示例。
  • 它是不是太大而无法适应内存巨人或...?
  • 大声笑。那里的答案爆炸式增长。我不介意过度发送我的解决方案......但无法理解。
  • @cagdasumay:一旦你发现你接受的解决方案如果数字在字符串的开头不会给你任何结果,请回来选择正确的解决方案。

标签: c# regex search


【解决方案1】:

如果你想使用正则表达式,你可以使用这个表达式:

[^\d](\d{13})[^\d]

这个只能抓取 13 个字符的长数字。

Regex101 Fiddle

使用您的 xml 代码更新
缩短了表达式

【讨论】:

  • 会吗?如果这个数字不在&lt;text&gt; 标签内?
  • 我看不到他只想在文本标签之间抓取的问题中的任何条件。 @cagdasumay 如果解决了,请考虑标记答案。否则,如果您真的需要文本标签过滤器,请告诉我。
  • 但是,这是一个错误的答案,因为它永远不会匹配字符串开头的数字。否定字符类与否定环视不同。请参阅我的答案中的正则表达式以获得正确的解决方案。
  • @stribizhev 感谢您提供信息!严重地不知道这一点。
  • @stribizhev:输入是 xml,因此字符串不可能位于文件的开头或结尾。它必须有某种封闭标签(据我所知),这意味着在任何有效字符串之前和之后总会有内容。我同意这是一个重要的观点,尽管关于所做的事情和消极的环视之间的差异。我主要只是不同意这个答案是错误的断言 - 对于这种特定情况,它会正常工作。
【解决方案2】:

如果您只希望从&lt;text&gt; 标签中获取数字,而其他标签也可能包含相似的数字,但您想避免匹配它们,请使用带有 XML 解析器的正则表达式。这是一个基于 XElement 的解决方案:

var xml = "<field name=\"TKT\"> - <item> <index>1</index> <text>Y24AUGXLOWS 2352159617737</text> </item> </field> - <field name=\"AP FAX\"> - <item> <index>1</index> <text>1 S1 SSRTKNETKHK1 2352159617737C1</text> </item> </field>";
var xe = XElement.Parse("<root>" + xml + "</root>");
var res = xe.Descendants("text").Select(p => p.Value).ToList();
var numbers = new List<string>();
foreach (var tag in res)
{ 
    numbers.AddRange(Regex.Matches(tag, @"(?<!\d)\d{12}(?!\d)").Cast<Match>().Select(n => n.Value).ToList());
}

对于任何处理“数字”提取的正则表达式,您应该了解它的边界并根据您的需要使用它:

  • \d{13} 将获取 13 位序列,即使它们是较长数字序列的一部分(1234567890123456 将为您提供 1234567890123
  • (?&lt;!\d)\d{13}(?!\d) 将得到所有 13 位序列如果后面没有或前面没有数字(因此,A1234567890123B 是有效匹配)
  • \b\d{13}\b 仅在包含非单词字符时才匹配(只有 ,1234567890123;-like 字符串是有效的匹配项。

【讨论】:

  • 顺便说一句,即使您不考虑解析 XML,我的正则表达式也可以与纯文本输入一起使用 var numbers = Regex.Matches(text, @"(?&lt;!\d)\d{12}(?!\d)").Cast&lt;Match&gt;().Select(n =&gt; n.Value).ToList());
【解决方案3】:

你也可以试试这个表达方式:

\b(\d{13})\b

Demo

请注意,它将从您的 xml 中捕获所有 13 位文本,如果您特别想定位 &lt;text&gt; 节点,也可以通过 xpath 查询。取自here的例子:

root.SelectNodes("html/body/.//*[(name() !='script') and (name()!='style')]/text()[string-length() > 200]")

【讨论】:

    【解决方案4】:

    您可以使用[^\d](\d{13})[^\d] 正则表达式来验证您的字符串。如果您想更改正则表达式中的字符串长度,只需将您想要的内容放在13

    【讨论】:

    • 这似乎与一小时前 C4ud3x 的回答相同,似乎没有添加任何内容...
    【解决方案5】:

    @"\d{13}?" 会给你 13 位数字:

    XDocument doc = XDocument.Load(filePath);
    
    var numbers = doc.Root.DescendantNodes().OfType<XText>()
                          .Where(t => Regex.IsMatch(t, @"\d{13}?"))
                          .Select(t => Regex.Match(t, @"\d{13}?").Value)
                          .ToList();
    

    【讨论】:

      【解决方案6】:

      C4ud3x 的回答其实是对的,但我认为也可以这样:([0-9]{13})

      【讨论】:

      • 它不能。他只想要 13 个字符长的字符串。这样,您还可以从字符串中抓取 13 个字符,例如 20 个字符,这不是他的目标。
      • 我知道,但我没看到他在哪里写错了
      猜你喜欢
      • 2016-03-26
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 2017-09-18
      • 2021-03-03
      相关资源
      最近更新 更多