C# 截取或匹配字符串内包含指定字符的一些方法

目录

核心正则表达式解析

方案一:提取所有符合条件的地址信息(推荐)

方案二:仅提取特定部分的数字(如只想要寝室号)

方案三:处理可能存在的格式差异(健壮性优化)

注意事项


如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

C# 截取或匹配字符串内包含指定字符,如:5号综合楼3层305寝2号 或 4号综合楼2层205寝1号。

针对字符串 "5号综合楼3层305寝2号或4号综合楼2层205寝1号",如果需要提取其中的结构化信息(如楼号、楼层、寝室号、床位号),最稳健的方法是使用 ‌正则表达式(Regex)‌ 进行分组捕获。

以下是具体的 C# 实现方案,分为‌提取单个结构‌和‌提取所有匹配项‌两种场景。

核心正则表达式解析

我们需要匹配的模式大致为:数字 + 号综合楼 + 数字 +  + 数字 +  + 数字 + 

正则表达式模式:

(\d+)号综合楼(\d+)层(\d+)寝(\d+)号

  • (\d+):捕获组,匹配一个或多个数字。
  • 第1组:楼号
  • 第2组:楼层
  • 第3组:寝室号
  • 第4组:床位/房间序号

方案一:提取所有符合条件的地址信息(推荐)

使用 Regex.Matches 可以一次性从长字符串中提取出所有符合该格式的地址块。

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class AddressExtractor
{
    // 定义地址数据模型
    public class DormInfo
    {
        public string BuildingNo { get; set; } // 楼号
        public string Floor { get; set; }      // 楼层
        public string RoomNo { get; set; }     // 寝室号
        public string BedNo { get; set; }      // 床位/序号
        public override string ToString()
        {
            return $"楼:{BuildingNo}, 层:{Floor}, 寝:{RoomNo}, 号:{BedNo}";
        }
    }

    public static List<DormInfo> ExtractAllAddresses(string input)
    {
        var results = new List<DormInfo>();
        if (string.IsNullOrEmpty(input)) return results;

        // 正则解释:
        // (\d+)       -> 捕获楼号
        // 号综合楼     -> 固定文字
        // (\d+)       -> 捕获楼层
        // 层           -> 固定文字
        // (\d+)       -> 捕获寝室号
        // 寝           -> 固定文字
        // (\d+)       -> 捕获床位号
        // 号           -> 固定文字
        string pattern = @"(\d+)号综合楼(\d+)层(\d+)寝(\d+)号";

        // 查找所有匹配项
        MatchCollection matches = Regex.Matches(input, pattern);

        foreach (Match match in matches)
        {
            if (match.Success)
            {
                results.Add(new DormInfo
                {
                    BuildingNo = match.Groups.Value, // 第1个括号内的内容
                    Floor = match.Groups.Value,      // 第2个括号内的内容
                    RoomNo = match.Groups.Value,     // 第3个括号内的内容
                    BedNo = match.Groups.Value       // 第4个括号内的内容
                });
            }
        }

        return results;
    }
}

// 调用示例
class Program
{
    static void Main()
    {
        string text = "5号综合楼3层305寝2号或4号综合楼2层205寝1号";
        
        var addresses = AddressExtractor.ExtractAllAddresses(text);

        foreach (var addr in addresses)
        {
            Console.WriteLine(addr.ToString());
        }
    }
}

输出结果:

楼:5, 层:3, 寝:305, 号:2
楼:4, 层:2, 寝:205, 号:1

方案二:仅提取特定部分的数字(如只想要寝室号)

如果你只关心“305”和“205”这样的寝室号,可以使用更简单的正则或 LINQ。

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

public class SimpleExtractor
{
    public static void Main()
    {
        string text = "5号综合楼3层305寝2号或4号综合楼2层205寝1号";

        // 方法:匹配 "数字+寝" 中的数字
        // 模式:(\d+)寝  -> 捕获"寝"字前面的数字
        string pattern = @"(\d+)寝";
        
        var roomNumbers = Regex.Matches(text, pattern)
                               .Cast<Match>()
                               .Select(m => m.Groups.Value)
                               .ToList();

        Console.WriteLine("提取到的寝室号: " + string.Join(", ", roomNumbers));
        // 输出: 提取到的寝室号: 305, 205
    }
}

方案三:处理可能存在的格式差异(健壮性优化)

如果实际数据中,“号综合楼”可能简写为“号楼”,或者“层”字可能缺失,建议优化正则使其更灵活。

优化后的正则:

(\d+)号(?:综合)?楼(\d+)层?(\d+)寝(\d+)号?

  • (?:综合)?:非捕获组,"综合"二字出现0次或1次。
  • 层?:"层"字出现0次或1次(防止有些数据写成 "3楼305寝")。
  • 号?:末尾的"号"字可选。

// 示例代码片段
string flexiblePattern = @"(\d+)号(?:综合)?楼(\d+)层?(\d+)寝(\d+)号?";
MatchCollection matches = Regex.Matches(input, flexiblePattern);
// 后续处理逻辑同上

注意事项

全角数字问题‌:如果输入可能包含全角数字(如“5号”),\d 默认在 .NET 中通常能匹配 Unicode 数字,但为了保险起见,可以在正则前加上 RegexOptions.ECMAScript 强制只匹配 ASCII 数字,或者手动扩展字符集 [0-90-9]。‌

性能优化‌:如果需要在循环中频繁执行提取,建议将 Regex 对象声明为 static readonly,以避免每次重复编译正则表达式。

private static readonly Regex AddressRegex = new Regex(@"(\d+)号综合楼(\d+)层(\d+)寝(\d+)号", RegexOptions.Compiled);

3‌.数据验证‌:提取出的字符串是 string 类型,如果需要用于计算或排序,建议使用 int.TryParse 转换为 int

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hefeng_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值