如何用C#正则分割Tesseract OCR识别的主机屏幕字符串?
用C#实现自定义规则的字符串分割
你的需求核心是把OCR识别后的字符串,按照指定的特殊字符集分割,同时保留这些特殊字符和后续关联的内容,还要区分开标签(不含特殊字符的部分)和对应的值(以特殊字符开头的部分)。用正则表达式是最直接的解决方案,因为它能灵活处理这种自定义的分割逻辑。
实现思路
我们需要匹配两种片段:
- 标签片段:由不包含
{ '@', '<', '>', '=', '$', '%', '&' }的字符组成(可以包含空格,比如示例里的"first name") - 值片段:以一个或多个上述特殊字符开头,后面跟着任意内容(包括空格)直到下一个标签出现前(或者字符串结尾)
通过正则表达式的捕获组,我们可以把这些片段分别提取出来,再整理成你需要的数组格式。
C#代码示例
using System; using System.Collections.Generic; using System.Text.RegularExpressions; public class StringSplitter { public static string[] SplitBySpecialChars(string input) { // 定义正则模式:匹配标签+值对,或者单独的标签/值 // 注意:$在正则里是特殊字符,需要转义成\\$ string pattern = @"(?:([^@<>=\\$%&]+?)\s+)?([@<>=\\$%&]+.*?)(?=\s+[^@<>=\\$%&]+|$)|([^@<>=\\$%&]+)"; MatchCollection matches = Regex.Matches(input, pattern); List<string> result = new List<string>(); foreach (Match match in matches) { // 添加非空的标签片段 if (!string.IsNullOrWhiteSpace(match.Groups[1].Value)) { result.Add(match.Groups[1].Value.Trim()); } // 添加非空的值片段 if (!string.IsNullOrWhiteSpace(match.Groups[2].Value)) { result.Add(match.Groups[2].Value.Trim()); } // 添加非空的单独标签片段 if (!string.IsNullOrWhiteSpace(match.Groups[3].Value)) { result.Add(match.Groups[3].Value.Trim()); } } return result.ToArray(); } // 测试示例 public static void Main() { string sampleInput = "first name => saran address @> my address"; string[] splitResult = SplitBySpecialChars(sampleInput); for (int i = 0; i < splitResult.Length; i++) { Console.WriteLine($"[{i}]: \"{splitResult[i]}\""); } } }
代码说明
正则模式解析:
([^@<>=\\$%&]+?):捕获标签片段,匹配任意非特殊字符([^...]表示反向匹配),+?是非贪婪匹配,避免过度匹配到后面的空格。\s+:匹配标签和值之间的空格分隔符。([@<>=\\$%&]+.*?):捕获值片段,匹配一个或多个特殊字符,然后跟着任意内容(.*?是非贪婪匹配,直到下一个标签出现)。(?=\s+[^@<>=\\$%&]+|$):正向前瞻,确保值片段在遇到下一个标签(空格+非特殊字符)或者字符串结尾时停止匹配。|([^@<>=\\$%&]+):匹配单独的标签片段,处理没有对应值的情况。
输出结果:运行上述代码,针对示例输入会得到你想要的数组:
[0]: "first name" [1]: "=> saran" [2]: "address" [3]: "@> my address"
边界情况处理
这段代码还能应对一些特殊场景:
- 如果输入开头就是特殊字符(比如
@> my address first name),会正确分割为["@> my address", "first name"] - 如果输入只有标签(比如
first name address),会分割为["first name", "address"] - 如果输入只有值(比如
=> saran),会分割为["=> saran"]
内容的提问来源于stack exchange,提问作者vijesh




