Groovy正则匹配Gradle命令输出失败,通用匹配/.+/也失效
问题与解决方案
问题场景
在Gradle脚本中尝试提取OS命令输出里的依赖DLL,使用正则:
def dlls = os.toString() =~ /Image has the following dependencies:\s+(.*)\s+Summary/
但无法匹配目标命令输出,甚至连os.toString() ==~ /.+/都返回false,匹配结果显示无匹配内容。
命令输出示例:
Dump of file C:\cygwin64\home\kannanj\grpc-java\compiler\build\artifacts\java_plugin\protoc-gen-grpc-java.exe File Type: EXECUTABLE IMAGE Image has the following dependencies: dbghelp.dll KERNEL32.dll Summary 6000 .data 31000 .rdata B000 .reloc 11C000 .text
核心原因
- 正则
.的默认限制:Java/Groovy正则中,.默认不匹配换行符(\n/\r),而命令输出是多行内容:==~ /.+/要求整个字符串由至少一个非换行字符组成,多行输出自然不满足,返回false。- 原正则里的
(.*)无法跨行匹配依赖项的多行内容,导致匹配失败。
- Windows换行符特性:命令输出使用
\r\n(CRLF)换行,进一步增加了跨行匹配的复杂度。
解决方法
1. 修复通用匹配问题
启用正则的DOTALL模式((?s)前缀),让.匹配包括换行在内的所有字符:
println os.toString() ==~ /(?s).+/ // 此时会返回true
2. 正确提取依赖DLL
调整正则,启用DOTALL并使用非贪婪匹配避免过度捕获,再处理提取到的内容:
def output = os.toString() // (?s)启用DOTALL,.*?非贪婪匹配依赖标题和Summary之间的内容 def matcher = output =~ /(?s)Image has the following dependencies:\s+(.*?)\s+Summary/ if (matcher.find()) { // 拆分多行,去除空白行和首尾空格 def dllList = matcher.group(1) .split(/\r?\n/) // 兼容Windows(\r\n)和Unix(\n)换行 .collect { it.trim() } .findAll() // 过滤空白字符串 // 输出结果:["dbghelp.dll", "KERNEL32.dll"] println dllList }
替代方案:精准匹配每行DLL
如果不需要捕获中间所有内容,也可以直接匹配所有符合格式的DLL行:
def dllMatcher = output =~ /\s+(\w+\.dll)/ def dllList = [] while (dllMatcher.find()) { dllList.add(dllMatcher.group(1)) } println dllList
内容的提问来源于stack exchange,提问作者Kannan J
相关产品推荐
相关产品推荐

