I often see post bar blocking various users’ posting content, and I thought about how to implement this. I thought about using strings to replaceAll to implement it, but this efficiency is very low and cannot guarantee the longest match. This is my initial idea at that time. In a project I recently worked on, I needed to block some content, and I analyzed this problem again, and finally formed the following code.
/** *@Description: masked word function implementation*/ package cn.yicha.novel.search.util; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashSet; import cn.yicha.novel.search.config.Config; public class Forbidden { private static Forbidden forbidden = new Forbidden(); //Mask word HashSet private HashSet<String> keyString = new HashSet<String>(); private final static int maxLength = Character.MAX_VALUE; //Mask word length HashSet array @SuppressWarnings("unchecked") private HashSet<Integer>[] keyLength = new HashSet[maxLength]; private Forbidden() { loadForbidden(Config.getClassRoot() + "forbidden.txt"); } public static Forbidden getForbidden(){ return forbidden; } /** * @param str * @return * @Description: The input string is masked to achieve maximum length matching*/ public String read(String str){ if (str == null){ return null; } StringBuffer stringBuffer = new StringBuffer(); int start = 0; for (int i = 0; i < str.length();){ int at = str.charAt(i); if (keyLength[at] == null){ i++; continue; } else { int ml = 0; for (Object obj : keyLength[at].toArray()){ int len = ((Integer)obj).intValue(); if (i + len <= str.length()){ String s = str.substring(i, i + len); if (keyString.contains(s)){ //Maximum length matching ml = len > ml ? len : ml; } } } if (ml > 0){ stringBuffer.append(str.substring(start, i)).append("***"); i += ml; start = i; } else { i++; } } } } if (start < str.length()){ stringBuffer.append(str.substring(start)); } return stringBuffer.toString(); } /** * @param path * @Description: Initialize the loading masking words * @Description: The data format logic for storing masking words is as follows * @Description: Build a HashSet<String> to store all masking words* @Description: Build a HashSet<Integer> array with length maxLength = Character.MAX_VALUE* @Description: Convert the first character in the loaded mask into an int value, that is, the position where the relevant information is stored in the array, * @Description: If "Hello" gets the int value of 'you' is 20320, that is, the relevant information of "Hello" is stored in the 20320 position of the array* @Description: The length of the mask word stored in each bit of the array is stored in the position of the HashSet<Integer> structure in the array is stored in that position*/ public void loadForbidden(String path){ File forbiddenFile = new File(path); FileInputStream fileInputStream; try { fileInputStream = new FileInputStream(forbiddenFile); InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String s; while ((s = bufferedReader.readLine()) != null){ s = s.trim(); if (s.length() > 0){ keyString.add(s); int i = s.charAt(0); if (keyLength[i] == null){ //Mask word length HashSet HashSet<Integer> a = new HashSet<Integer>(); a.add(s.length()); keyLength[i] = a; } else { keyLength[i].add(s.length()); } } } fileInputStream.close(); bufferedReader.close(); fileInputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { // System.out.println(Forbidden.getForbidden().read("AV actress nihao")); int i = 'you'; System.out.println(i); } }The above is the key code for Java to implement the blocking word function. I hope it will be helpful to everyone's learning.