Java中使用正则匹配DB('模式并提取子串的代码问题排查
问题排查与解决方案
首先,你的代码没有输出的原因主要有这几点:
- 错误使用split拆分字符串:你用逗号
,拆分字符串,但目标模式DB('可能出现在逗号分隔片段的中间(比如第一个片段是{'Opening Cost P&L per store','Opening Costs Capital per store','Average Monthly Revenue','GROSS MARGIN %'}] = N:DB('Store Cost),导致拆分后的片段无法完整匹配正则规则。 - matches方法的局限性:
String.matches()要求整个字符串完全匹配正则表达式,而拆分后的片段前面有大量无关内容,自然无法匹配DB\\('.+',所以没有输出。 - 正则表达式未满足匹配规则:你需要排除
S:DB('或DB('}这类变体,但原正则没有处理这些情况,也没有正确捕获单引号内的目标内容。
修正后的代码
下面是符合需求的实现,用Pattern和Matcher全局查找符合规则的匹配项,并提取单引号内的文本:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringRegex { public static void main(String[] args) { String str = "{'Opening Cost P&L per store','Opening Costs Capital per store','Average Monthly Revenue','GROSS MARGIN %'}] = N:DB('Store Cost', \n" + " !Country and Region, DB('New Store Plan', !Country and Region, \n" + " !ID numbers, !Budget version, 'Retailer Type'), ATTRS('New Stores', \n" + " !New Stores, '}Map_}Link_New Store Plan_3CStore Cost'), DB('New Store Plan', \n" + " !Country and Region, !ID numbers, !Budget version, 'Size'), \n" + " DB('New Store Plan', !Country and Region, !ID numbers, !Budget version, \n" + " 'Franchise/Corporate'), 'DATA')"; // 正则表达式解释: // (?<!\S) 确保DB('前面是空白或字符串开头,排除S:DB('这类前缀情况 // DB\(' 匹配DB(',转义特殊字符 // (?!}) 确保DB('后面不是},排除DB('}这类情况 // ([^']+) 捕获单引号内的所有非单引号字符(即我们要提取的内容) Pattern pattern = Pattern.compile("(?<!\\S)DB\\('(?!})([^']+)"); Matcher matcher = pattern.matcher(str); int count = 1; while (matcher.find()) { System.out.printf("%d - %s%n", count++, matcher.group(1)); } } }
代码说明
- 正则表达式:
(?<!\S)DB\('(?!})([^']+)精准符合你的匹配规则:排除带前缀的S:DB('和带}开头的DB('},只匹配独立的DB(',并捕获单引号内的文本。 - Matcher循环查找:通过
matcher.find()遍历字符串中所有符合规则的匹配项,避免了split拆分带来的问题。 - 输出格式:按照你示例中的格式,输出序号和提取的子串。
运行这段代码后,你会得到如下输出:
1 - Store Cost 2 - New Store Plan 3 - New Store Plan 4 - New Store Plan
内容的提问来源于stack exchange,提问作者sagar suri




