基于PdfSweep 4.0.1实现匹配字符串部分脱敏(留后四位)方案咨询
实现匹配字符串保留最后四位的PDF脱敏方案
要实现匹配字符串仅保留最后四位、其余部分脱敏的效果,你可以通过自定义清理策略扩展iText PdfSweep的RegexBasedCleanupStrategy,核心思路是精准控制脱敏覆盖的区域,只覆盖匹配文本的前n-4位,保留最后四位。
具体实现步骤
1. 自定义清理策略类
继承RegexBasedCleanupStrategy,重写getRedactions方法,根据匹配文本的长度计算需要脱敏的区域:
import com.itextpdf.kernel.colors.ColorConstants; import com.itextpdf.kernel.font.PdfFont; import com.itextpdf.kernel.geom.Rectangle; import com.itextpdf.pdfcleanup.autosweep.RegexBasedCleanupStrategy; import com.itextpdf.pdfcleanup.autosweep.ITextLocation; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; public class KeepLastFourCleanupStrategy extends RegexBasedCleanupStrategy { public KeepLastFourCleanupStrategy(Pattern pattern) { super(pattern); } @Override public List<Rectangle> getRedactions(ITextLocation location) { List<Rectangle> originalRedactions = super.getRedactions(location); if (originalRedactions.isEmpty()) { return originalRedactions; } String matchedText = location.getText(); // 文本长度≤4时不脱敏 if (matchedText.length() <= 4) { return Collections.emptyList(); } Rectangle originalRect = originalRedactions.get(0); PdfFont font = location.getFont(); float fontSize = location.getFontSize(); // 计算需要脱敏的前缀文本宽度 String prefixToRedact = matchedText.substring(0, matchedText.length() - 4); float redactWidth = font.getWidth(prefixToRedact, fontSize); // 构造仅覆盖前缀的脱敏矩形 Rectangle redactRect = new Rectangle( originalRect.getX(), originalRect.getY(), redactWidth, originalRect.getHeight() ); return Collections.singletonList(redactRect); } }
2. 替换原代码中的策略实例
使用自定义策略替代原RegexBasedCleanupStrategy,并指定目标匹配正则:
import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfReader; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.pdfcleanup.PdfCleaner; import com.itextpdf.pdfcleanup.autosweep.ICleanupStrategy; import java.io.File; import java.util.regex.Pattern; public class RedactPdfDemo { public static void main(String[] args) throws Exception { String SRC = "input.pdf"; // 你的源PDF路径 String DEST = new File(SRC).getParent() + "/redacted_output.pdf"; try (PdfDocument pdf = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST))) { // 示例:匹配"Alice"(大小写不敏感),可根据需求修改正则 ICleanupStrategy cleanupStrategy = new KeepLastFourCleanupStrategy( Pattern.compile("Alice", Pattern.CASE_INSENSITIVE) ).setRedactionColor(ColorConstants.PINK); PdfCleaner.autoSweepCleanUp(pdf, cleanupStrategy); } } }
关键细节说明
- 区域计算逻辑:通过
ITextLocation获取匹配文本的字体、字号,精准计算前缀文本的宽度,确保脱敏区域仅覆盖需要隐藏的部分。 - 边界处理:当匹配文本长度≤4时,直接跳过脱敏,避免误操作。
- 正则适配:你可以根据实际需求修改正则表达式(比如匹配手机号、身份证号等连续字符串),适配不同的脱敏场景。
备选方案(字体获取失败时)
如果遇到无法获取字体对象的场景(比如加密PDF或特殊嵌入字体),可以用比例估算的方式计算脱敏宽度:
// 替代原redactWidth计算逻辑 float totalWidth = originalRect.getWidth(); int totalLength = matchedText.length(); float redactWidth = totalWidth * (totalLength - 4) / totalLength;
内容的提问来源于stack exchange,提问作者Dadhustle
相关产品推荐
相关产品推荐

