【问题标题】:Seperating numbers, punctuation and letters trought the whole case在整个案例中分隔数字、标点和字母
【发布时间】:2020-05-07 08:53:52
【问题描述】:

我想要实现的目标: 将字符串拆分为数字、标点符号(除了 . 和 ,这些应该在数字部分中找到)和字母的单独部分。 示例:

案例 1: C_TANTALB

Result:

Alpha[]: C, TANTALB
Beta[]:
Zeta[]: _

案例 2: BGA-100_T0.8

Result:

Alpha[]: BGA, T
Beta[]: 100, 0.8
Zeta[]: -, _

案例 3: C0201

Result:

Alpha[]: C
Beta[]: 0201
Zeta[]: 

I've found this post 但它不是我的全部工作,因为它在示例 1 中失败,甚至没有返回 alpha 部分。而且它找不到标点符号。

如有任何帮助,将不胜感激。

【问题讨论】:

  • 答案有 IsLetterIsDigit.. 或许这些的简单组合会找到标点符号。
  • 我会牢记这一点,但要遍历所有字符,这将是一项相当繁重的操作。这个函数经常被调用,我想知道它是否有可能以更有效的方式
  • 这些字符串是否基于某种编码标准? “-”和“_”是唯一可能的“标点符号”吗?
  • 测试字符串的所有字符的唯一方法是对其进行迭代。这些都是简单的操作,我不希望有任何性能问题。您可以尝试使用正则表达式。喜欢([a-zA-Z]+)|(\d+)|([^a-zA-Z\d])。您甚至可以添加名称组
  • 如果你有多个 - 或 _ 会发生什么?

标签: c#


【解决方案1】:

如果用IsDigitIsLetter 迭代字符串测试有点复杂,
您可以为此使用正则表达式:(?<Alfas>[a-zA-Z]+)|(?<Digits>\d+)|(?<Others>[^a-zA-Z\d])

1/。命名为捕获组 Alfas (?<Alfas>[a-zA-Z]+)

匹配下面列表中的单个字符 [a-zA-Z]+

a-z 介于 a(索引 97)和 z(索引 122)之间的单个字符(区分大小写)
A-Z 介于 A(索引 65)和 Z(索引 90)之间的单个字符(区分大小写)

+ 量词 - 匹配一次到无限次,尽可能多次,按需回馈(贪婪)

2/.命名捕获组数字(?<Digits>[\d,.]+)

\d+ 匹配一个数字(等于 [0-9])
+ 量词 - 匹配一次到无限次,尽可能多次,根据需要返回(贪心)

3/.命名为捕获组其他人(?<Others>[^a-zA-Z\d]+)

匹配下面列表中的单个字符 [^a-zA-Z\d]

a-z 介于 a(索引 97)和 z(索引 122)之间的单个字符(区分大小写)
A-Z 介于 A(索引 65)和 Z(索引 90)之间的单个字符(区分大小写)
\d 匹配一个数字(等于 [0-9])

+ 量词 - 匹配一次到无限次,尽可能多次,按需回馈(贪婪)

然后得到一个goup值:

var matches = Regex.Matches(testInput, pattern).Cast<Match>();
            
var alfas = matches.Where(x => !string.IsNullOrEmpty(x.Groups["Alfas"].Value))
                    .Select(x=> x.Value)
                    .ToList();

LiveDemo

【讨论】:

  • 喜欢你的解决方案,我想抓住一件事。和 , 在数字组中。我已将表达式更改为:@"(?[a-zA-Z]+)|(?\d.,+)|(?[^a-zA-Z\ d])" 但这似乎并没有达到我的预期,我需要如何更改表达式才能捕获 .并且,在数字组中?示例:XXX6.5YYY45 所以应该在数字组中找到 6.5 作为匹配项
  • \d+,表示多位数字。您的版本\d.,+,表示一个数字,然后是一个点,然后是多个逗号。但是数字的 rgex 很快就会变得复杂,例如 stackoverflow.com/questions/38439618/regex-allow-dot-and-comma
  • 在尝试了一些事情之后,我发现:(?&lt;Alfas&gt;[a-zA-Z]+)|(?&lt;Digits&gt;[\d,.]+)|(?&lt;Others&gt;[^a-zA-Z\d]) 仍在运行一些测试,但这似乎是我正在寻找的东西
  • 它需要一组比 6.5 => 6.5 更复杂的规则。什么是百位和小数分隔符。因为它可以根据文化进行交换。百位分隔符是否准确(wellplace)?比如“1,000”是1000,“10,00”是10和00。我们允许“.5”是0,5吗?*
  • [\d,.]+ 将允许 ,.,.,.,.,..,.,.成为一个数字..您可以使用一些工具来玩耍并测试您是否没有规则集regex101.com/r/n7iwGd/1
【解决方案2】:

可能最简单的方法是使用 3 个单独的正则表达式;每类字符一个。

  • [A-Za-z]+ 用于字母序列
  • [\d.,]+ 用于数字
  • [-_]+ 标点符号(暂时不完整;请随时扩展列表)

例子:

using System;
using System.Linq;
using System.Text.RegularExpressions;

class MainClass
{
  private static readonly Regex _regexAlpha = new Regex(@"[A-Za-z]+");
  private static readonly Regex _regexBeta = new Regex(@"[\d.,]+");
  private static readonly Regex _regexZeta = new Regex(@"[-_]+");

  public static void Main (string[] args)
  {
    Console.Write("Input: ");
    string input = Console.ReadLine();

    var resultAlpha = _regexAlpha.Matches(input).Select(m => m.Value);
    var resultBeta = _regexBeta.Matches(input).Select(m => m.Value);
    var resultZeta = _regexZeta.Matches(input).Select(m => m.Value);

    Console.WriteLine($"Alpha: {string.Join(", ", resultAlpha)}");
    Console.WriteLine($"Beta: {string.Join(", ", resultBeta)}");
    Console.WriteLine($"Zeta: {string.Join(", ", resultZeta)}");
  }
}

示例输出:

Input: ABC_3.14m--nop
Alpha: ABC, m, nop
Beta: 3.14
Zeta: _, --

现场演示:https://repl.it/repls/LopsidedUsefulBucket

【讨论】:

    猜你喜欢
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多