【问题标题】:Regex alternative for extracting numeric and non-numeric strings用于提取数字和非数字字符串的正则表达式替代方法
【发布时间】:2018-07-31 12:56:46
【问题描述】:

使用下面的表达式,我可以获得预期的输出并提取数字或字符串并拆分为字符串数组。

Regex _re = new Regex(@"(?<=\D)(?=\d)|(?<=\d)(?=\D)", RegexOptions.Compiled);

_re.Split("2323dfdf233fgfgfg ddfdf334").Dump();  //string can be any alphanumeric start with

如何在不使用 Regex 的情况下实现相同的目标?我需要解析每个字符并隔离吗?我有大量文本需要处理才能提取,但我不能使用正则表达式作为提供的输入。

【问题讨论】:

  • 没有正则表达式?那你可以用什么?
  • 通过使用循环或 linq 或任何替代的最佳解决方案。所以,处理大字符串时不会命中。
  • 那么,你尝试了什么呢?
  • 那么,你为什么不想使用正则表达式呢?正则表达式最优解。你为什么要重新发明轮子并为自己做额外的工作?
  • true,它是使用正则表达式的最佳选择,但根据给定的说明,需要实现替代选项。

标签: c# regex linq logic alphanumeric


【解决方案1】:

对于 Linq 解决方案,您可以结合使用 Enumerable.Skip()Enumerable.TakeWhile() 同时检查 char.IsDigit() 以确定字符是否为数字。例如:

string inputString = "2323dfdf233fgfgfg ddfdf334";
var list = new List<string>();

int usedLength = 0;
while (usedLength < inputString.Length)
{
    bool isDigit = char.IsDigit(inputString[usedLength]);
    string item = string.Concat(inputString.Skip(usedLength).
                                            TakeWhile((c) => char.IsDigit(c) == isDigit));
    usedLength += item.Length;
    list.Add(item);
};

然后就可以轻松遍历列表了:

foreach (string item in list)
    Console.WriteLine(item);

输出:

2323
dfdf
233
fgfgfg ddfdf
334

【讨论】:

  • 可枚举的方法似乎会令人难以置信地降低性能。最好在我的解决方案中使用简单循环。
【解决方案2】:

这个解决方案足够快。检查更大的字符串。

string str = "2323dfdf233fgfgfg ddfdf334"; 

var strings = new List<string>();
var sb = new StringBuilder();
var lastCharIsNumber = char.IsDigit(str[0]);

foreach (var c in str) {
    if (char.IsDigit(c) ) {
        if (!lastCharIsNumber) {
            strings.Add(sb.ToString());
            sb.Clear();
        }
        lastCharIsNumber = true;
    }
    else {
        if (lastCharIsNumber) {
            strings.Add(sb.ToString());
            sb.Clear();
        }
        lastCharIsNumber = false;
    }
    sb.Append(c);
}
strings.Add(sb.ToString());
strings.Dump();

【讨论】:

  • char.IsDigit 可以替换为 Predicate&lt;char&gt; IsNumber = (c) =&gt; c &gt;= 48 &amp;&amp; c &lt;= 57; 之类的东西,但这似乎并没有快多少。
  • 不错的答案! +1。在处理大字符串时,与 Linq 相比,它实际上更快。不过有一件事:你几乎可以用一个相当短的版本(没有其他)替换你的if..else语句:if (char.IsDigit(c) != lastCharIsNumber) { lastCharIsNumber = !lastCharIsNumber; // .... }
猜你喜欢
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 2023-03-22
  • 1970-01-01
  • 2011-05-10
  • 2022-11-03
  • 1970-01-01
相关资源
最近更新 更多