You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅提取字符串中任意位置的YYYYmmDD格式日期?

问题:提取字符串中YYYYMMDD格式的日期

我有一个包含YYYYMMDD格式日期的字符串,日期位置不固定,还夹杂其他数字序列,示例如下:

xx12x20240113yyyy123zzzz
20240201xxxx34yyy
xxxxxx20240315yyy1224zzz

目前我通过循环逐个测试数字序列来提取日期,但希望找到更简洁优雅的方法。当前使用的C#代码如下:

private bool InvoiceData(string Filename, out string Invoice, out String InvoiceDate, out string Error)
{
    bool Esito = false;
    Invoice = "";
    InvoiceDate = "";
    Error = "";

    try 
    {
        int nPos = 0;
        int nPos2 = 0;
        string sTemp = Filename;
        string sTemp2 = "";

        while ((nPos = sTemp.IndexOfAny("0123456789".ToCharArray())) >= 0)
        {
            sTemp2 = sTemp.Substring(nPos, 8);
            if (sTemp2.All(char.IsNumber))
            {
                string[] formats = { "yyyyMMdd" };
                if (InvoiceDate == "" && DateTime.TryParseExact(sTemp2, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dDataFattura))
                {
                    InvoiceDate = dDataFattura.ToString("yyyyMMdd");
                }
            }
            else
            {
                if (Invoice == "")
                {
                    nPos2 = sTemp.Substring(nPos).IndexOf("_");     // This is by Design
                    Invoice = Filename.Substring(nPos, nPos2);
                }
            }

            nPos2 = 0;
            while (Char.IsDigit(sTemp2[nPos2++]) && nPos2 < sTemp2.Length) { }
            sTemp = sTemp.Substring(nPos + nPos2);
        }
        if (InvoiceDate != "" && Invoice != "") { Esito = true; }
    }
    catch (Exception ex)
    {
        Error = ex.Message;
    }
    return Esito; 
}

请问是否存在更简洁的方式提取该格式的日期?


更简洁的实现方案

可以用正则表达式配合日期验证来实现,代码更简洁易读,逻辑也更清晰:

核心思路

  1. 用正则匹配字符串中所有连续的8位数字(\d{8}),这些是潜在的YYYYMMDD格式日期
  2. 对每个匹配结果,用DateTime.TryParseExact验证是否为合法日期
  3. 提取第一个符合要求的日期(或所有符合的,根据需求调整)

优化后的代码

using System.Text.RegularExpressions;
using System.Globalization;

private bool InvoiceData(string filename, out string invoice, out string invoiceDate, out string error)
{
    invoice = string.Empty;
    invoiceDate = string.Empty;
    error = string.Empty;

    try
    {
        // 提取第一个符合YYYYMMDD格式的日期
        var dateMatches = Regex.Matches(filename, @"\d{8}");
        foreach (Match match in dateMatches)
        {
            if (DateTime.TryParseExact(match.Value, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
            {
                invoiceDate = date.ToString("yyyyMMdd");
                break; // 找到第一个有效日期就停止
            }
        }

        // 提取Invoice(用正则简化原逻辑)
        var invoiceMatch = Regex.Match(filename, @"\d+_");
        if (invoiceMatch.Success)
        {
            invoice = invoiceMatch.Value.TrimEnd('_');
        }

        return !string.IsNullOrEmpty(invoice) && !string.IsNullOrEmpty(invoiceDate);
    }
    catch (Exception ex)
    {
        error = ex.Message;
        return false;
    }
}

代码说明

  • 日期提取:正则\d{8}直接定位所有8位数字序列,避免了手动循环查找数字的繁琐;通过TryParseExact确保只有合法的YYYYMMDD格式日期会被提取
  • Invoice提取:用正则\d+_匹配数字加下划线的序列,直接提取数字部分,替代原代码中手动查找索引的逻辑,更简洁
  • 整体代码去掉了复杂的循环索引操作,可读性和维护性大幅提升

内容的提问来源于stack exchange,提问作者user24145613

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:50:17