Sensitive-word adalah alat kata sensitif berkinerja tinggi berdasarkan algoritma DFA.
Pengalaman online
Jika Anda memiliki beberapa penyakit yang sulit dan rumit, Anda dapat bergabung: Grup Pertukaran Teknis
Sensitive-word-admin adalah aplikasi konsol yang sesuai. Fungsi saat ini sedang dalam tahap awal pengembangan dan versi MVP tersedia.
Halo semuanya, saya Lao Ma.
Saya selalu ingin menerapkan alat kata yang sederhana dan mudah digunakan, jadi saya mengimplementasikan alat ini open source.
Berdasarkan implementasi algoritma DFA, konten tesaurus sensitif saat ini mencakup 6W+ (file sumber 18W+, setelah satu penghapusan).
Pada tahap selanjutnya, tesaurus sensitif akan terus dioptimalkan dan ditambah, dan kinerja algoritma akan lebih ditingkatkan.
V0.24.0 telah mulai mendukung klasifikasi dan penyempurnaan kata -kata sensitif, tetapi beban kerja relatif besar, jadi ada kelalaian yang pasti.
Selamat datang di PR Perbaikan, Permintaan GitHub, atau bergabung dengan Grup Pertukaran Teknis untuk berkomunikasi dan membual!
6W+ tesaurus, dan optimasi dan pembaruan berkelanjutan
Berdasarkan implementasi fasih-API, penggunaan yang elegan dan ringkas
Berdasarkan algoritma DFA, kinerja adalah 7W+ QPS, aplikasi tidak sensitif
Mendukung operasi umum seperti penilaian, pengembalian, dan desensitisasi kata -kata sensitif
Mendukung konversi format umum
Pertukaran setengah lebar selebar lebar, pertukaran kasus bahasa Inggris, bentuk-bentuk jumlah yang umum, Cina tradisional dan Cina yang disederhanakan, bentuk-bentuk umum pertukaran bahasa Inggris, mengabaikan kata-kata duplikat, dll.
Dukungan Deteksi Kata Sensitif, Deteksi Email, Deteksi Digital, Deteksi Situs Web, IPv4, dll.
Mendukung Kebijakan Penggantian Kustom
Mendukung kata-kata sensitif dan whitel yang ditentukan pengguna
Mendukung Pembaruan Data Dinamis (Kustomisasi Pengguna), efektif dalam waktu nyata
Mendukung antarmuka tag + implementasi klasifikasi bawaan untuk kata-kata sensitif
Dukungan melewatkan beberapa karakter khusus untuk membuat pencocokan lebih fleksibel
Mendukung penambahan tunggal/modifikasi daftar hitam dan putih, tanpa inisialisasi lengkap
Change_log.md
Terkadang ada konsol untuk kata -kata sensitif, yang membuatnya lebih fleksibel dan nyaman untuk dikonfigurasi.
Bagaimana cara mengimplementasikan layanan konsol kata sensitif di luar kotak?
Sejumlah besar file tag kata sensitif telah disortir, yang dapat membuat kata -kata sensitif kita lebih nyaman.
Kedua bahan ini dapat dibaca dalam artikel di bawah ini:
V0.11.0 Fitur-fitur baru dari kata-kata sensitif dan file tag yang sesuai
Saat ini, v0.24.0 memiliki tag kata bawaan, dan disarankan untuk meningkatkan ke versi terbaru jika diperlukan.
Sumber terbuka tidak mudah. Jika proyek ini bermanfaat bagi Anda, Anda dapat mengundang Lao Ma untuk minum secangkir teh susu.

Jdk1.8+
Maven 3.x+
< dependency >
< groupId >com.github.houbb</ groupId >
< artifactId >sensitive-word</ artifactId >
< version >0.24.0</ version >
</ dependency > SensitiveWordHelper adalah kelas alat untuk kata -kata sensitif. Metode inti adalah sebagai berikut:
Catatan: SensitiveWordHelper menyediakan konfigurasi default. Jika Anda ingin membuat konfigurasi khusus yang fleksibel, silakan merujuk ke konfigurasi fitur kelas boot
| metode | parameter | Nilai pengembalian | menjelaskan |
|---|---|---|---|
| Berisi (string) | String yang akan diverifikasi | Nilai Boolean | Pastikan string itu berisi kata -kata sensitif |
| ganti (string, isensitivewordreplace) | Ganti kata sensitif dengan strategi penggantian yang ditentukan | Rangkaian | Mengembalikan string yang desensitisasi |
| ganti (string, char) | Gunakan char yang ditentukan untuk menggantikan kata sensitif | Rangkaian | Mengembalikan string yang desensitisasi |
| ganti (string) | Gunakan * untuk menggantikan kata -kata sensitif | Rangkaian | Mengembalikan string yang desensitisasi |
| findAll (string) | String yang akan diverifikasi | Daftar string | Mengembalikan semua kata sensitif dalam string |
| findFirst (string) | String yang akan diverifikasi | Rangkaian | Mengembalikan kata sensitif pertama dalam string |
| findAll (string, iWordresulthandler) | Kelas pemrosesan hasil IWordresulthandler | Daftar string | Mengembalikan semua kata sensitif dalam string |
| findFirst (string, iwordresulthandler) | Kelas pemrosesan hasil IWordresulthandler | Rangkaian | Mengembalikan kata sensitif pertama dalam string |
| tag (string) | Dapatkan tag untuk kata -kata sensitif | String kata sensitif | Kembali ke daftar tag untuk kata -kata sensitif |
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
Assert . assertTrue ( SensitiveWordHelper . contains ( text )); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
String word = SensitiveWordHelper . findFirst ( text );
Assert . assertEquals ( "五星红旗" , word );SensitiveWordHelper.findFirst (teks) setara dengan:
String word = SensitiveWordHelper . findFirst ( text , WordResultHandlers . word ()); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
List < String > wordList = SensitiveWordHelper . findAll ( text );
Assert . assertEquals ( "[五星红旗, 毛主席, 天安门]" , wordList . toString ());Mengembalikan semua penggunaan kata sensitif mirip dengan sensitiveWordHelper.findFirst (), dan juga mendukung penentu kelas pemrosesan hasil.
SensitiveWordHelper.findall (teks) setara dengan:
List < String > wordList = SensitiveWordHelper . findAll ( text , WordResultHandlers . word ());Wordresulthandlers.raw () dapat menyimpan informasi subskrip dan kategori yang sesuai:
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
// 默认敏感词标签为空
List < WordTagsDto > wordList1 = SensitiveWordHelper . findAll ( text , WordResultHandlers . wordTags ());
Assert . assertEquals ( "[WordTagsDto{word='五星红旗', tags=[]}, WordTagsDto{word='毛主席', tags=[]}, WordTagsDto{word='天安门', tags=[]}]" , wordList1 . toString ()); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
String result = SensitiveWordHelper . replace ( text );
Assert . assertEquals ( "****迎风飘扬,***的画像屹立在***前。" , result ); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
String result = SensitiveWordHelper . replace ( text , '0' );
Assert . assertEquals ( "0000迎风飘扬,000的画像屹立在000前。" , result );V0.2.0 mendukung fitur ini.
Deskripsi Adegan: Terkadang kami ingin kata -kata sensitif yang berbeda memiliki hasil penggantian yang berbeda. Misalnya, [Game] diganti dengan [e-sports], dan [pengangguran] diganti dengan [pekerjaan fleksibel].
Diakui, tidak apa -apa untuk menggunakan penggantian string string di muka, tetapi kinerjanya rata -rata.
Contoh Penggunaan:
/**
* 自定替换策略
* @since 0.2.0
*/
@ Test
public void defineReplaceTest () {
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
ISensitiveWordReplace replace = new MySensitiveWordReplace ();
String result = SensitiveWordHelper . replace ( text , replace );
Assert . assertEquals ( "国家旗帜迎风飘扬,教员的画像屹立在***前。" , result );
} Di antara mereka, MySensitiveWordReplace adalah kebijakan penggantian kami yang disesuaikan, yang diimplementasikan sebagai berikut:
public class MyWordReplace implements IWordReplace {
@ Override
public void replace ( StringBuilder stringBuilder , final char [] rawChars , IWordResult wordResult , IWordContext wordContext ) {
String sensitiveWord = InnerWordCharUtils . getString ( rawChars , wordResult );
// 自定义不同的敏感词替换策略,可以从数据库等地方读取
if ( "五星红旗" . equals ( sensitiveWord )) {
stringBuilder . append ( "国家旗帜" );
} else if ( "毛主席" . equals ( sensitiveWord )) {
stringBuilder . append ( "教员" );
} else {
// 其他默认使用 * 代替
int wordLength = wordResult . endIndex () - wordResult . startIndex ();
for ( int i = 0 ; i < wordLength ; i ++) {
stringBuilder . append ( '*' );
}
}
}
} Kami melakukan pemetaan tetap untuk beberapa kata, dan yang lainnya dikonversi menjadi * secara default.
IwordResulthandler dapat memproses hasil kata -kata sensitif dan memungkinkan pengguna untuk menyesuaikannya.
Lihat Kelas Alat WordResultHandlers untuk Implementasi bawaan:
Hanya kata -kata sensitif yang dilestarikan.
Simpan informasi yang terkait dengan kata -kata sensitif, termasuk subskrip awal dan akhir dari kata -kata sensitif.
Pada saat yang sama, kata -kata dan informasi label kata yang sesuai disimpan.
Lihat SensitiveWordHelpertest untuk semua kasus uji
1) Contoh dasar
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
List < String > wordList = SensitiveWordHelper . findAll ( text );
Assert . assertEquals ( "[五星红旗, 毛主席, 天安门]" , wordList . toString ());
List < String > wordList2 = SensitiveWordHelper . findAll ( text , WordResultHandlers . word ());
Assert . assertEquals ( "[五星红旗, 毛主席, 天安门]" , wordList2 . toString ());
List < IWordResult > wordList3 = SensitiveWordHelper . findAll ( text , WordResultHandlers . raw ());
Assert . assertEquals ( "[WordResult{startIndex=0, endIndex=4}, WordResult{startIndex=9, endIndex=12}, WordResult{startIndex=18, endIndex=21}]" , wordList3 . toString ()); Kami menentukan informasi tag dari kata yang sesuai dalam file dict_tag_test.txt .
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
// 默认敏感词标签为空
List < WordTagsDto > wordList1 = SensitiveWordHelper . findAll ( text , WordResultHandlers . wordTags ());
Assert . assertEquals ( "[WordTagsDto{word='五星红旗', tags=[]}, WordTagsDto{word='毛主席', tags=[]}, WordTagsDto{word='天安门', tags=[]}]" , wordList1 . toString ());
List < WordTagsDto > wordList2 = SensitiveWordBs . newInstance ()
. wordTag ( WordTags . file ( "dict_tag_test.txt" ))
. init ()
. findAll ( text , WordResultHandlers . wordTags ());
Assert . assertEquals ( "[WordTagsDto{word='五星红旗', tags=[政治, 国家]}, WordTagsDto{word='毛主席', tags=[政治, 伟人, 国家]}, WordTagsDto{word='天安门', tags=[政治, 国家, 地址]}]" , wordList2 . toString ());Fitur selanjutnya terutama ditujukan untuk berbagai pemrosesan yang menargetkan berbagai situasi, sehingga dapat meningkatkan laju hit kata -kata sensitif sebanyak mungkin.
Ini adalah pertempuran panjang pelanggaran dan pertahanan.
final String text = "fuCK the bad words." ;
String word = SensitiveWordHelper . findFirst ( text );
Assert . assertEquals ( "fuCK" , word ); final String text = "fuck the bad words." ;
String word = SensitiveWordHelper . findFirst ( text );
Assert . assertEquals ( "fuck" , word );Di sini, konversi bentuk umum digital diimplementasikan.
final String text = "这个是我的微信:9⓿二肆⁹₈③⑸⒋➃㈤㊄" ;
List < String > wordList = SensitiveWordBs . newInstance (). enableNumCheck ( true ). init (). findAll ( text );
Assert . assertEquals ( "[9⓿二肆⁹₈③⑸⒋➃㈤㊄]" , wordList . toString ()); final String text = "我爱我的祖国和五星紅旗。" ;
List < String > wordList = SensitiveWordHelper . findAll ( text );
Assert . assertEquals ( "[五星紅旗]" , wordList . toString ()); final String text = "Ⓕⓤc⒦ the bad words" ;
List < String > wordList = SensitiveWordHelper . findAll ( text );
Assert . assertEquals ( "[Ⓕⓤc⒦]" , wordList . toString ()); final String text = "ⒻⒻⒻfⓤuⓤ⒰cⓒ⒦ the bad words" ;
List < String > wordList = SensitiveWordBs . newInstance ()
. ignoreRepeat ( true )
. init ()
. findAll ( text );
Assert . assertEquals ( "[ⒻⒻⒻfⓤuⓤ⒰cⓒ⒦]" , wordList . toString ());Informasi pribadi seperti alamat email tidak diaktifkan secara default.
final String text = "楼主好人,邮箱 [email protected]" ;
List < String > wordList = SensitiveWordBs . newInstance (). enableEmailCheck ( true ). init (). findAll ( text );
Assert . assertEquals ( "[[email protected]]" , wordList . toString ());Umumnya digunakan untuk memfilter informasi iklan seperti nomor ponsel/qq, dan tidak diaktifkan secara default.
Setelah v0.2.1, panjang yang terdeteksi oleh numCheckLen(长度) didukung.
final String text = "你懂得:12345678" ;
// 默认检测 8 位
List < String > wordList = SensitiveWordBs . newInstance ()
. enableNumCheck ( true )
. init (). findAll ( text );
Assert . assertEquals ( "[12345678]" , wordList . toString ());
// 指定数字的长度,避免误杀
List < String > wordList2 = SensitiveWordBs . newInstance ()
. enableNumCheck ( true )
. numCheckLen ( 9 )
. init ()
. findAll ( text );
Assert . assertEquals ( "[]" , wordList2 . toString ());Digunakan untuk memfilter informasi URL umum, tidak diaktifkan secara default.
v0.18.0 mengoptimalkan deteksi URL, yang lebih ketat dan mengurangi tingkat kesalahan penilaian
final String text = "点击链接 https://www.baidu.com 查看答案" ;
final SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance (). enableUrlCheck ( true ). init ();
List < String > wordList = sensitiveWordBs . findAll ( text );
Assert . assertEquals ( "[https://www.baidu.com]" , wordList . toString ());
Assert . assertEquals ( "点击链接 ********************* 查看答案" , sensitiveWordBs . replace ( text ));Dukungan v0.17.0
Hindari pengguna yang melewati deteksi URL melalui IP, dll., Yang tidak diaktifkan secara default.
final String text = "个人网站,如果网址打不开可以访问 127.0.0.1。" ;
final SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance (). enableIpv4Check ( true ). init ();
List < String > wordList = sensitiveWordBs . findAll ( text );
Assert . assertEquals ( "[127.0.0.1]" , wordList . toString ());Fitur di atas semuanya diaktifkan secara default, dan kadang -kadang bisnis perlu secara fleksibel mendefinisikan fitur konfigurasi terkait.
Jadi V0.0.14 membuka konfigurasi properti.
Untuk menggunakan lebih elegan, definisi ini secara seragam digunakan oleh FLUENT-API.
Pengguna dapat menggunakan SensitiveWordBs untuk mendefinisikannya sebagai berikut:
CATATAN: Setelah konfigurasi, gunakan objek SensitiveWordBs yang baru didefinisikan alih -alih metode alat sebelumnya. Konfigurasi metode alat semuanya default.
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. ignoreCase ( true )
. ignoreWidth ( true )
. ignoreNumStyle ( true )
. ignoreChineseStyle ( true )
. ignoreEnglishStyle ( true )
. ignoreRepeat ( false )
. enableNumCheck ( false )
. enableEmailCheck ( false )
. enableUrlCheck ( false )
. enableIpv4Check ( false )
. enableWordCheck ( true )
. numCheckLen ( 8 )
. wordTag ( WordTags . none ())
. charIgnore ( SensitiveWordCharIgnores . defaults ())
. wordResultCondition ( WordResultConditions . alwaysTrue ())
. init ();
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
Assert . assertTrue ( wordBs . contains ( text ));Deskripsi setiap konfigurasi adalah sebagai berikut:
| Nomor seri | metode | menjelaskan | nilai default |
|---|---|---|---|
| 1 | Ignorecase | Abaikan kasus | BENAR |
| 2 | ketidaktahuan | Abaikan sudut setengah sudut bulat | BENAR |
| 3 | IgnorenumStyle | Abaikan penulisan angka | BENAR |
| 4 | Abaikan Chinesestyle | Abaikan format penulisan Cina | BENAR |
| 5 | absainenglishstyle | Abaikan format penulisan bahasa Inggris | BENAR |
| 6 | Ignorerepeat | Abaikan kata -kata duplikat | PALSU |
| 7 | enablenumcheck | Apakah akan mengaktifkan deteksi digital. | PALSU |
| 8 | EnableMailCheck | Deteksi email diaktifkan | PALSU |
| 9 | enableUrlCheck | Apakah akan mengaktifkan deteksi tautan | PALSU |
| 10 | enableipv4check | Apakah akan mengaktifkan deteksi IPv4 | PALSU |
| 11 | enableWordcheck | Apakah akan mengaktifkan deteksi kata yang sensitif | BENAR |
| 12 | numchecklen | Deteksi digital, sesuaikan panjang yang ditentukan. | 8 |
| 13 | wordtag | Tag kata yang sesuai | tidak ada |
| 14 | Charignore | Karakter yang diabaikan | tidak ada |
| 15 | WordresultCondition | Pemrosesan tambahan untuk pencocokan kata -kata sensitif, seperti membatasi kebutuhan untuk kecocokan penuh kata -kata bahasa Inggris | Selalu benar |
V0.16.1 didukung. Terkadang kita perlu membebaskan memori, yang bisa sebagai berikut:
Tentang masalah daur ulang memori
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. init ();
// 后续因为一些原因移除了对应信息,希望释放内存。
wordBs . destroy ();Skenario Penggunaan: Setelah inisialisasi, kami ingin menambahkan/menghapus satu kata alih -alih menghidupkannya kembali sepenuhnya. Fitur ini disiapkan untuk ini.
Versi yang Didukung: V0.19.0
addWord(word) menambahkan kata -kata sensitif, mendukung kata/koleksi tunggal
removeWord(word) Menghapus kata -kata yang sensitif, mendukung kata/koleksi tunggal
final String text = "测试一下新增敏感词,验证一下删除和新增对不对" ;
SensitiveWordBs sensitiveWordBs =
SensitiveWordBs . newInstance ()
. wordAllow ( WordAllows . empty ())
. wordDeny ( WordDenys . empty ())
. init ();
// 当前
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());
// 新增单个
sensitiveWordBs . addWord ( "测试" );
sensitiveWordBs . addWord ( "新增" );
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());
// 删除单个
sensitiveWordBs . removeWord ( "新增" );
Assert . assertEquals ( "[测试]" , sensitiveWordBs . findAll ( text ). toString ());
sensitiveWordBs . removeWord ( "测试" );
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());
// 新增集合
sensitiveWordBs . addWord ( Arrays . asList ( "新增" , "测试" ));
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());
// 删除集合
sensitiveWordBs . removeWord ( Arrays . asList ( "新增" , "测试" ));
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());
// 新增数组
sensitiveWordBs . addWord ( "新增" , "测试" );
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());
// 删除集合
sensitiveWordBs . removeWord ( "新增" , "测试" );
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());Skenario Penggunaan: Setelah inisialisasi, kami ingin menambahkan/menghapus satu kata alih -alih menghidupkannya kembali sepenuhnya. Fitur ini disiapkan untuk ini.
Versi yang Didukung: V0.21.0
addWordAllow(word) menambahkan daftar putih baru, mendukung kata/koleksi tunggal
removeWordAllow(word) Menghapus daftar putih, mendukung kata/koleksi tunggal
final String text = "测试一下新增敏感词白名单,验证一下删除和新增对不对" ;
SensitiveWordBs sensitiveWordBs =
SensitiveWordBs . newInstance ()
. wordAllow ( WordAllows . empty ())
. wordDeny ( new IWordDeny () {
@ Override
public List < String > deny () {
return Arrays . asList ( "测试" , "新增" );
}
})
. init ();
// 当前
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());
// 新增单个
sensitiveWordBs . addWordAllow ( "测试" );
sensitiveWordBs . addWordAllow ( "新增" );
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());
// 删除单个
sensitiveWordBs . removeWordAllow ( "测试" );
Assert . assertEquals ( "[测试]" , sensitiveWordBs . findAll ( text ). toString ());
sensitiveWordBs . removeWordAllow ( "新增" );
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());
// 新增集合
sensitiveWordBs . addWordAllow ( Arrays . asList ( "新增" , "测试" ));
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());
// 删除集合
sensitiveWordBs . removeWordAllow ( Arrays . asList ( "新增" , "测试" ));
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());
// 新增数组
sensitiveWordBs . addWordAllow ( "新增" , "测试" );
Assert . assertEquals ( "[]" , sensitiveWordBs . findAll ( text ). toString ());
// 删除集合
sensitiveWordBs . removeWordAllow ( "新增" , "测试" );
Assert . assertEquals ( "[测试, 新增, 新增]" , sensitiveWordBs . findAll ( text ). toString ());Metode ini ditinggalkan . Disarankan untuk menggunakan metode penambahan tambahan di atas untuk menghindari pemuatan penuh. Untuk kompatibilitas, metode ini tetap ada.
Cara menggunakan: Saat memanggil sensitiveWordBs.init() , membangun kembali kosakata sensitif berdasarkan iWordDeny+iWordAllow. Karena inisialisasi dapat memakan waktu lama (tingkat kedua), semua optimasi untuk INIT tidak akan mempengaruhi fungsi kosakata lama ketika tidak selesai, dan yang baru akan menang setelah selesai .
@ Component
public class SensitiveWordService {
@ Autowired
private SensitiveWordBs sensitiveWordBs ;
/**
* 更新词库
*
* 每次数据库的信息发生变化之后,首先调用更新数据库敏感词库的方法。
* 如果需要生效,则调用这个方法。
*
* 说明:重新初始化不影响旧的方法使用。初始化完成后,会以新的为准。
*/
public void refresh () {
// 每次数据库的信息发生变化之后,首先调用更新数据库敏感词库的方法,然后调用这个方法。
sensitiveWordBs . init ();
}
} Seperti disebutkan di atas, Anda dapat secara aktif memicu inisialisasi sensitiveWordBs.init(); Ketika leksikon database berubah, dan database perlu berlaku.
Penggunaan lain tetap sama tanpa memulai kembali aplikasi.
Versi yang Didukung: V0.13.0
Kadang -kadang kita mungkin ingin lebih membatasi kata -kata sensitif yang cocok, misalnya, meskipun kita mendefinisikan [AV] sebagai kata sensitif, kita tidak ingin [harus] dicocokkan.
Anda dapat menyesuaikan antarmuka WordresultCondition dan menerapkan kebijakan Anda sendiri.
Kebijakan bawaan di WordResultConditions#alwaysTrue() selalu benar, sedangkan WordResultConditions#englishWordMatch() mensyaratkan bahwa bahasa Inggris harus cocok dengan kata lengkap.
Kelas Alat WordresultConditions bisa mendapatkan kebijakan yang cocok
| menyelesaikan | menjelaskan | Versi yang didukung |
|---|---|---|
| selalu true | Selalu benar | |
| Bahasa Inggris WordMatch | Kata bahasa Inggris kata lengkap pencocokan | V0.13.0 |
| Bahasa Inggris WordNumchch | Kata bahasa Inggris/angka pencocokan kata lengkap | V0.20.0 |
| wordtags | Mereka yang memuaskan tag spesifik, seperti hanya berfokus pada tag [iklan] | V0.23.0 |
| Rantai (IWordResultCondition ... Kondisi) | Mendukung menentukan beberapa kondisi dan memuaskannya secara bersamaan | V0.23.0 |
Situasi default asli:
final String text = "I have a nice day。" ;
List < String > wordList = SensitiveWordBs . newInstance ()
. wordDeny ( new IWordDeny () {
@ Override
public List < String > deny () {
return Collections . singletonList ( "av" );
}
})
. wordResultCondition ( WordResultConditions . alwaysTrue ())
. init ()
. findAll ( text );
Assert . assertEquals ( "[av]" , wordList . toString ());Kami dapat menentukan bahwa bahasa Inggris harus cocok dengan kata lengkap.
final String text = "I have a nice day。" ;
List < String > wordList = SensitiveWordBs . newInstance ()
. wordDeny ( new IWordDeny () {
@ Override
public List < String > deny () {
return Collections . singletonList ( "av" );
}
})
. wordResultCondition ( WordResultConditions . englishWordMatch ())
. init ()
. findAll ( text );
Assert . assertEquals ( "[]" , wordList . toString ());Tentu saja, strategi yang lebih kompleks dapat diimplementasikan sesuai kebutuhan.
Versi yang Didukung: v0.23.0
Kami hanya dapat mengembalikan kata -kata sensitif yang berafiliasi dengan label tertentu.
Kami telah menentukan dua kata sensitif: Produk, AV
Mywordtag adalah implementasi tag kata yang sensitif yang kami definisikan:
/**
* 自定义单词标签
* @since 0.23.0
*/
public class MyWordTag extends AbstractWordTag {
private static Map < String , Set < String >> dataMap ;
static {
dataMap = new HashMap <>();
dataMap . put ( "商品" , buildSet ( "广告" , "中文" ));
dataMap . put ( "AV" , buildSet ( "色情" , "单词" , "英文" ));
}
private static Set < String > buildSet ( String ... tags ) {
Set < String > set = new HashSet <>();
for ( String tag : tags ) {
set . add ( tag );
}
return set ;
}
@ Override
protected Set < String > doGetTag ( String word ) {
return dataMap . get ( word );
}
}Misalnya, kami mensimulasikan dua kelas implementasi yang berbeda, masing -masing berfokus pada tag kata yang berbeda.
// 只关心SE情
SensitiveWordBs sensitiveWordBsYellow = SensitiveWordBs . newInstance ()
. wordDeny ( new IWordDeny () {
@ Override
public List < String > deny () {
return Arrays . asList ( "商品" , "AV" );
}
})
. wordAllow ( WordAllows . empty ())
. wordTag ( new MyWordTag ())
. wordResultCondition ( WordResultConditions . wordTags ( Arrays . asList ( "色情" )))
. init ();
// 只关心广告
SensitiveWordBs sensitiveWordBsAd = SensitiveWordBs . newInstance ()
. wordDeny ( new IWordDeny () {
@ Override
public List < String > deny () {
return Arrays . asList ( "商品" , "AV" );
}
})
. wordAllow ( WordAllows . empty ())
. wordTag ( new MyWordTag ())
. wordResultCondition ( WordResultConditions . wordTags ( Arrays . asList ( "广告" )))
. init ();
final String text = "这些 AV 商品什么价格?" ;
Assert . assertEquals ( "[AV]" , sensitiveWordBsYellow . findAll ( text ). toString ());
Assert . assertEquals ( "[商品]" , sensitiveWordBsAd . findAll ( text ). toString ());Kata -kata sensitif kita umumnya lebih kontinu, seperti [topi konyol]
Lalu ada penemuan cerdas bahwa Anda dapat menambahkan beberapa karakter di tengah, seperti [konyol! @#$ Topi] Untuk melewatkan deteksi, tetapi kekuatan serangan bersumpah tidak berkurang.
Jadi, bagaimana menangani skenario serupa ini?
Kita dapat menentukan set skip karakter khusus dan mengabaikan karakter yang tidak berarti ini.
V0.11.0 memulai dukungan
Strategi karakter yang sesuai dengan Charignore dapat ditentukan secara fleksibel oleh pengguna.
final String text = "傻@冒,狗+东西" ;
//默认因为有特殊字符分割,无法识别
List < String > wordList = SensitiveWordBs . newInstance (). init (). findAll ( text );
Assert . assertEquals ( "[]" , wordList . toString ());
// 指定忽略的字符策略,可自行实现。
List < String > wordList2 = SensitiveWordBs . newInstance ()
. charIgnore ( SensitiveWordCharIgnores . specialChars ())
. init ()
. findAll ( text );
Assert . assertEquals ( "[傻@冒, 狗+东西]" , wordList2 . toString ());Terkadang kami ingin menambahkan label rahasia ke kata -kata sensitif: seperti situasi sosial, kekerasan, dll.
Dengan cara ini, lebih banyak karakteristik dapat dilakukan sesuai dengan label, dll., Seperti hanya memproses jenis label tertentu.
Versi yang Didukung: V0.10.0
Versi Dukungan Fitur Utama: V0.24.0
Ini hanyalah antarmuka abstrak, dan pengguna dapat mendefinisikan implementasi sendiri. Misalnya, dari kueri basis data, pembacaan file, panggilan API, dll.
public interface IWordTag {
/**
* 查询标签列表
* @param word 脏词
* @return 结果
*/
Set < String > getTag ( String word );
} Untuk memfasilitasi penggunaan di sebagian besar situasi, beberapa strategi adegan diimplementasikan di kelas WordTags
| Metode implementasi | menjelaskan | Komentar |
|---|---|---|
| tidak ada() | Implementasi kosong | Dukungan v0.10.0 |
| file (string filepath) | Tentukan jalur file | Dukungan v0.10.0 |
| File (String FilePath, String WordsPlit, String TagsPlit) | Tentukan jalur file, serta pemisah kata dan pemisah tag | Dukungan v0.10.0 |
| peta (peta akhir <string, set> wordtagmap) | Inisialisasi Menurut Peta | V0.24.0 Dukungan |
| garis (garis koleksi) | Daftar string | V0.24.0 Dukungan |
| baris (baris koleksi, string wordsplit, string tagspli) | Daftar string, serta pemisah kata dan pemisah label | V0.24.0 Dukungan |
| sistem() | Implementasi bawaan file sistem, mengintegrasikan klasifikasi jaringan | V0.24.0 Dukungan |
| default () | Kebijakan default saat ini adalah sistem | V0.24.0 Dukungan |
| Rantai (Iwordtag ... Lainnya) | Metode rantai, mendukung integrasi pengguna untuk mengimplementasikan beberapa kebijakan | V0.24.0 Dukungan |
Format tag kata sensitif yang kami default ke敏感词tag1,tag2 , yang berarti bahwa tag dari敏感词adalah tag1 dan tag2.
Misalnya
五星红旗 政治,国家
Ini juga disarankan untuk semua konten baris file dan konten string yang ditentukan. Jika tidak puas, terapkan cukup dengan cara khusus.
Dimulai dengan v0.24.0, tag kata default adalah WordTags.system() .
Catatan: Saat ini, statistik data berasal dari internet, dan ada banyak kelalaian. Setiap orang juga dipersilakan untuk memperbaiki masalah dan terus meningkatkan ...
SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance ()
. wordTag ( WordTags . system ())
. init ();
Set < String > tagSet = sensitiveWordBs . tags ( "博彩" );
Assert . assertEquals ( "[3]" , tagSet . toString ());Di sini, untuk mengoptimalkan ukuran kompresi, kategori yang sesuai diwakili oleh angka.
Daftar makna angka adalah sebagai berikut:
0 政治
1 毒品
2 色情
3 赌博
4 违法
Di sini kami mengambil file sebagai contoh untuk menunjukkan cara menggunakannya.
final String path = "~ \ test \ resources \ dict_tag_test.txt" ;
// 演示默认方法
IWordTag wordTag = WordTags . file ( path );
SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance ()
. wordTag ( wordTag )
. init ();
Set < String > tagSet = sensitiveWordBs . tags ( "零售" );
Assert . assertEquals ( "[广告, 网络]" , tagSet . toString ());
// 演示指定分隔符
IWordTag wordTag2 = WordTags . file ( path , " " , "," );
SensitiveWordBs sensitiveWordBs2 = SensitiveWordBs . newInstance ()
. wordTag ( wordTag2 )
. init ();
Set < String > tagSet2 = sensitiveWordBs2 . tags ( "零售" );
Assert . assertEquals ( "[广告, 网络]" , tagSet2 . toString ()); Di mana dict_tag_test.txt konten khusus kami adalah sebagai berikut:
零售 广告,网络
Saat kami mendapatkan kata -kata sensitif, kami dapat mengatur strategi pemrosesan hasil yang sesuai untuk mendapatkan informasi tag kata sensitif yang sesuai
// 自定义测试标签类
IWordTag wordTag = WordTags . lines ( Arrays . asList ( "天安门 政治,国家,地址" ));
// 指定初始化
SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance ()
. wordTag ( wordTag )
. init ()
;
List < WordTagsDto > wordTagsDtoList1 = sensitiveWordBs . findAll ( "天安门" , WordResultHandlers . wordTags ());
Assert . assertEquals ( "[WordTagsDto{word='天安门', tags=[政治, 国家, 地址]}]" , wordTagsDtoList1 . toString ()); Kami menyesuaikan tag untuk kata kunci天安门, dan kemudian menentukan bahwa strategi pemrosesan hasil FindAll adalah WordResultHandlers.wordTags() , dan kami dapat memperoleh daftar tag yang sesuai sambil mendapatkan kata -kata sensitif.
Kadang -kadang kami ingin merancang pemuatan kata -kata sensitif menjadi dinamis, seperti modifikasi konsol, yang kemudian dapat berlaku secara real time.
V0.0.13 mendukung fitur ini.
Untuk mengimplementasikan fitur ini dan kompatibel dengan fungsi sebelumnya, kami mendefinisikan dua antarmuka.
Antarmuka adalah sebagai berikut, Anda dapat menyesuaikan implementasi Anda sendiri.
Daftar yang dikembalikan berarti bahwa kata itu adalah kata yang sensitif.
/**
* 拒绝出现的数据-返回的内容被当做是敏感词
* @author binbin.hou
* @since 0.0.13
*/
public interface IWordDeny {
/**
* 获取结果
* @return 结果
* @since 0.0.13
*/
List < String > deny ();
}Misalnya:
public class MyWordDeny implements IWordDeny {
@ Override
public List < String > deny () {
return Arrays . asList ( "我的自定义敏感词" );
}
}Antarmuka adalah sebagai berikut, Anda dapat menyesuaikan implementasi Anda sendiri.
Daftar yang dikembalikan berarti bahwa kata itu bukan kata yang sensitif.
/**
* 允许的内容-返回的内容不被当做敏感词
* @author binbin.hou
* @since 0.0.13
*/
public interface IWordAllow {
/**
* 获取结果
* @return 结果
* @since 0.0.13
*/
List < String > allow ();
}menyukai:
public class MyWordAllow implements IWordAllow {
@ Override
public List < String > allow () {
return Arrays . asList ( "五星红旗" );
}
}Setelah antarmuka disesuaikan, tentu saja, perlu ditentukan untuk berlaku.
Untuk memanfaatkan lebih elegan, kami merancang SensitiveWordBs Class Boot.
Anda dapat menentukan kata-kata sensitif melalui wordeny (), wordAllow () menentukan kata-kata yang tidak sensitif, dan menginisialisasi kamus kata-kata sensitif melalui init ().
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. wordDeny ( WordDenys . defaults ())
. wordAllow ( WordAllows . defaults ())
. init ();
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
Assert . assertTrue ( wordBs . contains ( text ));Catatan: init () memakan waktu untuk membangun kata sensitif DFA. Secara umum disarankan agar diinisialisasi hanya sekali saat menerapkan inisialisasi. Alih -alih mengulangi inisialisasi!
Kami dapat menguji implementasi khusus, sebagai berikut:
String text = "这是一个测试,我的自定义敏感词。" ;
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. wordDeny ( new MyWordDeny ())
. wordAllow ( new MyWordAllow ())
. init ();
Assert . assertEquals ( "[我的自定义敏感词]" , wordBs . findAll ( text ). toString ()); Inilah satu -satunya di mana我的自定义敏感词adalah kata -kata sensitif, dan测试bukanlah kata -kata sensitif.
Tentu saja, berikut adalah semua implementasi khusus kami. Secara umum disarankan untuk menggunakan konfigurasi default + konfigurasi kustom sistem.
Metode berikut dapat digunakan.
Metode WordDenys.chains() menggabungkan beberapa implementasi menjadi IWordDENY yang sama.
Metode WordAllows.chains() menggabungkan beberapa implementasi ke dalam iWordAllow yang sama.
contoh:
String text = "这是一个测试。我的自定义敏感词。" ;
IWordDeny wordDeny = WordDenys . chains ( WordDenys . defaults (), new MyWordDeny ());
IWordAllow wordAllow = WordAllows . chains ( WordAllows . defaults (), new MyWordAllow ());
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. wordDeny ( wordDeny )
. wordAllow ( wordAllow )
. init ();
Assert . assertEquals ( "[我的自定义敏感词]" , wordBs . findAll ( text ). toString ());Semuanya menggunakan konfigurasi default sistem dan konfigurasi khusus secara bersamaan.
Catatan: Kami menginisialisasi WordB baru, jadi gunakan WordB baru untuk menilai. Alih -alih menggunakan metode SensitiveWordHelper sebelumnya, konfigurasi metode alat adalah default!
Dalam penggunaan aktual, misalnya, Anda dapat memodifikasi konfigurasi halaman dan kemudian berlaku secara real time.
Data disimpan dalam database. Berikut ini adalah contoh kode semu. Anda dapat merujuk ke SpringsensitiveWordConfig.java
Diperlukan, versi v0.0.15 dan di atas.
Kode semu yang disederhanakan adalah sebagai berikut, dan sumber data adalah database.
MyDDwordAllow dan MyDDwordDeny adalah kelas implementasi khusus berdasarkan basis data sebagai sumbernya.
@ Configuration
public class SpringSensitiveWordConfig {
@ Autowired
private MyDdWordAllow myDdWordAllow ;
@ Autowired
private MyDdWordDeny myDdWordDeny ;
/**
* 初始化引导类
* @return 初始化引导类
* @since 1.0.0
*/
@ Bean
public SensitiveWordBs sensitiveWordBs () {
SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance ()
. wordAllow ( WordAllows . chains ( WordAllows . defaults (), myDdWordAllow ))
. wordDeny ( myDdWordDeny )
// 各种其他配置
. init ();
return sensitiveWordBs ;
}
}Inisialisasi kosakata sensitif memakan waktu, sehingga disarankan untuk melakukan inisialisasi inisial sekali ketika program dimulai.
Setelah v0.6.0, tambahkan tes benchmark yang sesuai.
BenchmarkTimestest
Lingkungan uji adalah buku catatan normal:
处理器 12th Gen Intel(R) Core(TM) i7-1260P 2.10 GHz
机带 RAM 16.0 GB (15.7 GB 可用)
系统类型 64 位操作系统, 基于 x64 的处理器
PS: Lingkungan yang berbeda akan bervariasi, tetapi proporsinya pada dasarnya stabil.
Data uji: 100+ string, loop 10W kali.
| Nomor seri | Pemandangan | memakan waktu | Komentar |
|---|---|---|---|
| 1 | Hanya membuat kata -kata sensitif tanpa konversi format apa pun | 1470ms, sekitar 7.2W QPS | Mengejar kinerja ekstrem, Anda dapat mengonfigurasinya seperti ini |
| 2 | Hanya membuat kata -kata sensitif, mendukung semua konversi format | 2744ms, sekitar 3.7W QPS | Temui sebagian besar skenario |
Hapus kata -kata sensitif dari karakter Cina individu. Di Cina, frasa harus dianggap sebagai satu kata untuk mengurangi tingkat kesalahan penilaian.
Mendukung perubahan kata sensitif individu?
Hapus, tambahkan, edit?
Dukungan antarmuka tag kata sensitif
Tag dukungan saat memproses kata -kata sensitif
Perbandingan Penggunaan Memori + Optimalisasi WordData
Pengguna menentukan frasa khusus, dan memungkinkan kombinasi frasa yang ditentukan diperoleh, membuatnya lebih fleksibel
FormatCombine/CheckCombine/AllowdenyCombine Kombinasi Kebijakan, memungkinkan kustomisasi pengguna.
Optimalisasi Strategi Pemeriksaan Kata, Konversi Traversal + Terpadu
Tambahkan Threadlocal dan Optimalisasi Kinerja Lainnya
Konsol Kata Sensitif-Sensitif-Sensitif V1.2.0 Open Source
Bagaimana cara mendukung penyebaran terdistribusi dalam rilis V1.3.0 yang sensitif-kata?
01-Beginner alat kata sensitif sumber terbuka
02-bagaimana menerapkan alat kata yang sensitif? Klarifikasi gagasan menerapkan kata -kata terlarang
03-Support Word Stopword Stop Optimization dan Simbol Khusus
04-Dictionary of Sensitive Words Slimming
Penjelasan 05-rebus tentang algoritma DFA dari kata-kata sensitif (algoritma trie pohon)
06 Kata-kata yang peka (kata-kata kotor) Bagaimana cara mengabaikan karakter yang tidak berarti? Mencapai efek penyaringan yang lebih baik
V0.10.0 Dukungan preliminer untuk tag klasifikasi kata kotor
v0.11.0 - Fitur baru dari kata -kata sensitif: abaikan karakter yang tidak berarti, kamus tag kata
V0.12.0 Kata yang sensitif/kemampuan pelabelan kata kotor semakin ditingkatkan
V0.13.0 Rilis Fitur Word yang Sensitif Mendukung Pencocokan Kata Lengkap dalam Kata Bahasa Inggris
V0.16.1 Kamus Memori Rilis Sumber Daya dari Fitur Baru dari Kata Sensitif
V0.19.0 - Kata -kata sensitif dengan fitur baru dari kata -kata sensitif yang diedit secara individual tanpa inisialisasi berulang
v0.20.0 Karakteristik baru dari kata -kata sensitif cocok dengan semua angka, bukan kecocokan parsial
V0.21.0 Whiteelists dengan fitur baru dari kata -kata sensitif mendukung pengeditan tunggal, memperbaiki masalah saat whitelist berisi daftar hitam
pinyin ke pinyin
pinyin2hanzi pinyin ke karakter Cina
segmen segmentasi kata Cina berkinerja tinggi
opencc4j Konversi Cina Tradisional Cina Tradisional Sederhana
Kesamaan karakter Cina NLP-Hanzi-Similar
Deteksi ejaan pemeriksaan kata
Kata-kata sensitif kata sensitif