iText7 PDFSweep正则红报Nullable对象非空异常问题咨询
\s?触发"Nullable object must have a value"异常的排查与解决 我来帮你拆解这个问题——你遇到的这个System.InvalidOperationException: Nullable object must have a value异常,其实和iText7的RegexBasedLocationExtractionStrategy内部处理捕获组的逻辑有关,咱们一步步说清楚:
关于你的两个疑惑
疑惑1:添加\s?明明只是扩大匹配范围,为什么会出问题?
你说得没错,\s?理论上只是允许匹配前置的可选空白字符,逻辑上应该只扩大匹配范围,但问题出在正则的捕获组设计上。你的正则@"(\s?7-\d\d\d\d)"把\s?和目标文本放在了同一个捕获组里,而当\s?匹配到0个空白字符时,这个捕获组的匹配内容其实是从"7-"开始,但iText7的位置提取策略在处理这种包含可选空匹配的捕获组时,内部的Nullable类型变量可能没有被正确初始化。
疑惑2:为什么正则匹配结果会触发异常?
看你的异常堆栈,问题根源在RegexBasedLocationExtractionStrategy.GetResultantLocations()方法里。iText7的这个策略类在处理带捕获组的正则时,默认假设每个捕获组都有有效的非空匹配位置,但当你的捕获组因为\s?的存在出现了空匹配分支(比如目标文本里的"7-XXXX"前面没有空白字符时),对应的位置信息就变成了未赋值的Nullable值,代码直接访问这个值就抛出了空值异常。
可行的解决办法
改用非捕获组避免空匹配处理
把正则调整为@"(?:\s?)7-\d\d\d\d",用(?:...)定义非捕获组,这样既保留了可选空白的匹配逻辑,又不会让iText7去处理捕获组的空值问题,完全符合你的需求。调整捕获组范围,只捕获有效内容
如果需要单独捕获"7-XXXX"部分,把\s?放在捕获组外面:@"\s?(7-\d\d\d\d)"。这样捕获组只会匹配非空的目标文本,不会出现空匹配的情况,也能绕过异常。升级iText7版本
这个问题大概率是iText7的一个已知bug,如果你使用的是较旧的PDFSweep版本,尝试升级到最新稳定版,官方可能已经修复了捕获组空匹配的处理逻辑。
你可以先试试第一种方案,应该能立刻解决问题,同时保留你想要的匹配规则。
内容的提问来源于stack exchange,提问作者frostwolfer

