目录

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。
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。
如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。
2784

被折叠的 条评论
为什么被折叠?



