Sensitive-Word เป็นเครื่องมือคำที่ละเอียดอ่อนประสิทธิภาพสูงตามอัลกอริทึม DFA
ประสบการณ์ออนไลน์
หากคุณมีโรคที่ยากและซับซ้อนคุณสามารถเข้าร่วม: กลุ่มแลกเปลี่ยนทางเทคนิค
Sensitive-word-admin เป็นแอปพลิเคชันคอนโซลที่สอดคล้องกัน ขณะนี้ฟังก์ชั่นอยู่ในช่วงเริ่มต้นของการพัฒนาและรุ่น MVP พร้อมใช้งาน
สวัสดีทุกคนฉันเป็นลาวมา
ฉันต้องการใช้เครื่องมือคำที่ละเอียดอ่อนและง่ายต่อการใช้งานอยู่เสมอดังนั้นฉันจึงใช้โอเพ่นซอร์สเครื่องมือนี้
จากการใช้งานอัลกอริทึม DFA เนื้อหาของอรรถาภิธานที่ละเอียดอ่อนในปัจจุบันมี 6W+ (ไฟล์ต้นฉบับ 18W+ หลังจากการลบหนึ่งครั้ง)
ในระยะต่อมาอรรถาภิธานที่มีความละเอียดอ่อนจะได้รับการปรับปรุงและเสริมอย่างต่อเนื่องและประสิทธิภาพของอัลกอริทึมจะได้รับการปรับปรุงเพิ่มเติม
v0.24.0 เริ่มสนับสนุนการจำแนกและการปรับแต่งของคำที่ละเอียดอ่อน แต่ภาระงานมีขนาดค่อนข้างใหญ่ดังนั้นจึงมีการละเว้นอย่างหลีกเลี่ยงไม่ได้
ยินดีต้อนรับสู่การปรับปรุง PR คำขอ GitHub หรือเข้าร่วมกลุ่มแลกเปลี่ยนทางเทคนิคเพื่อสื่อสารและคุยโว!
6W+ อรรถาภิธานและการเพิ่มประสิทธิภาพและการปรับปรุงอย่างต่อเนื่อง
ขึ้นอยู่กับการใช้งาน Flue-API การใช้งานที่สง่างามและรัดกุม
จากอัลกอริทึม DFA ประสิทธิภาพคือ 7W+ QPS แอปพลิเคชันไม่รู้สึกตัว
สนับสนุนการดำเนินการทั่วไปเช่นการตัดสินการกลับและการ desensitization ของคำที่ละเอียดอ่อน
รองรับการแปลงรูปแบบทั่วไป
การแลกเปลี่ยนครึ่งความกว้างแบบเต็มความกว้าง, การแลกเปลี่ยนกรณีภาษาอังกฤษ, รูปแบบทั่วไปของตัวเลข, จีนดั้งเดิมและภาษาจีนง่าย ๆ , รูปแบบทั่วไปของการแลกเปลี่ยนภาษาอังกฤษ, ไม่สนใจคำที่ซ้ำกัน ฯลฯ
รองรับการตรวจจับคำที่ละเอียดอ่อนการตรวจจับอีเมลการตรวจจับดิจิตอลการตรวจจับเว็บไซต์ IPv4 ฯลฯ
สนับสนุนนโยบายการเปลี่ยนที่กำหนดเอง
รองรับคำศัพท์ที่ละเอียดอ่อนและผู้ใช้งานที่ผู้ใช้กำหนด
รองรับการอัปเดตข้อมูลแบบไดนามิก (การปรับแต่งผู้ใช้) มีผลบังคับใช้แบบเรียลไทม์
รองรับแท็กอินเตอร์เฟส + การใช้การจำแนกประเภทในตัวสำหรับคำที่ละเอียดอ่อน
รองรับการข้ามอักขระพิเศษบางอย่างเพื่อให้การจับคู่มีความยืดหยุ่นมากขึ้น
รองรับการเพิ่ม/ดัดแปลงรายการขาวดำเพียงครั้งเดียวโดยไม่ต้องเริ่มต้นเต็มรูปแบบ
Change_log.md
บางครั้งมีคอนโซลสำหรับคำที่ละเอียดอ่อนซึ่งทำให้มีความยืดหยุ่นและสะดวกในการกำหนดค่า
จะใช้บริการคอนโซลคำที่ละเอียดอ่อนนอกกรอบได้อย่างไร?
ไฟล์แท็กคำที่ละเอียดอ่อนจำนวนมากได้รับการคัดออกซึ่งสามารถทำให้คำที่ละเอียดอ่อนของเราสะดวกยิ่งขึ้น
วัสดุทั้งสองนี้สามารถอ่านได้ในบทความด้านล่าง:
คุณสมบัติ v0.11.0-new ของคำที่ละเอียดอ่อนและไฟล์แท็กที่เกี่ยวข้อง
ปัจจุบัน V0.24.0 มีแท็กคำในตัวและขอแนะนำให้อัปเกรดเป็นเวอร์ชันล่าสุดหากจำเป็น
โอเพ่นซอร์สไม่ใช่เรื่องง่าย หากโครงการนี้เป็นประโยชน์กับคุณคุณสามารถเชิญลาวมาให้ดื่มน้ำนมหนึ่งถ้วย

JDK1.8+
Maven 3.x+
< dependency >
< groupId >com.github.houbb</ groupId >
< artifactId >sensitive-word</ artifactId >
< version >0.24.0</ version >
</ dependency > SensitiveWordHelper เป็นคลาสเครื่องมือสำหรับคำที่ละเอียดอ่อน วิธีการหลักมีดังนี้:
หมายเหตุ: SensitiveWordHelper มีการกำหนดค่าเริ่มต้น หากคุณต้องการสร้างการกำหนดค่าแบบกำหนดเองที่ยืดหยุ่นโปรดดูการกำหนดค่าคุณสมบัติคลาสบูตคลาส
| วิธี | พารามิเตอร์ | ค่าส่งคืน | อธิบาย |
|---|---|---|---|
| มี (สตริง) | สตริงที่จะตรวจสอบ | ค่าบูลีน | ตรวจสอบว่าสตริงมีคำที่ละเอียดอ่อน |
| แทนที่ (String, isensitivewordreplace) | แทนที่คำที่ละเอียดอ่อนด้วยกลยุทธ์การเปลี่ยนที่ระบุ | สาย | ส่งคืนสตริง desensitized |
| แทนที่ (สตริง, ถ่าน) | ใช้ถ่านที่ระบุเพื่อแทนที่คำที่ละเอียดอ่อน | สาย | ส่งคืนสตริง desensitized |
| แทนที่ (สตริง) | ใช้ * เพื่อแทนที่คำที่ละเอียดอ่อน | สาย | ส่งคืนสตริง desensitized |
| findall (สตริง) | สตริงที่จะตรวจสอบ | รายการสตริง | ส่งคืนคำศัพท์ที่ละเอียดอ่อนทั้งหมดในสตริง |
| findfirst (สตริง) | สตริงที่จะตรวจสอบ | สาย | ส่งคืนคำที่ละเอียดอ่อนครั้งแรกในสตริง |
| findall (สตริง, iwordresulthandler) | IWORDRESULTHANDLER คลาสการประมวลผลผลลัพธ์ | รายการสตริง | ส่งคืนคำศัพท์ที่ละเอียดอ่อนทั้งหมดในสตริง |
| FindFirst (String, iWordResulthandler) | IWORDRESULTHANDLER คลาสการประมวลผลผลลัพธ์ | สาย | ส่งคืนคำที่ละเอียดอ่อนครั้งแรกในสตริง |
| แท็ก (สตริง) | รับแท็กสำหรับคำที่ละเอียดอ่อน | สตริงคำที่ละเอียดอ่อน | กลับไปที่รายการแท็กสำหรับคำที่ละเอียดอ่อน |
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
Assert . assertTrue ( SensitiveWordHelper . contains ( text )); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
String word = SensitiveWordHelper . findFirst ( text );
Assert . assertEquals ( "五星红旗" , word );SensitiveWordHelper.FindFirst (ข้อความ) เทียบเท่ากับ:
String word = SensitiveWordHelper . findFirst ( text , WordResultHandlers . word ()); final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
List < String > wordList = SensitiveWordHelper . findAll ( text );
Assert . assertEquals ( "[五星红旗, 毛主席, 天安门]" , wordList . toString ());ส่งคืนการใช้คำที่ละเอียดอ่อนทั้งหมดคล้ายกับ SensitiveWordHelper.FindFirst () และยังรองรับการระบุคลาสการประมวลผลผลลัพธ์
SensitiveWordHelper.Findall (ข้อความ) เทียบเท่ากับ:
List < String > wordList = SensitiveWordHelper . findAll ( text , WordResultHandlers . word ());WordResulthandlers.raw () สามารถเก็บข้อมูลข้อมูลย่อยและข้อมูลหมวดหมู่ที่เกี่ยวข้อง:
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 รองรับคุณสมบัตินี้
คำอธิบายฉาก: บางครั้งเราต้องการคำที่ละเอียดอ่อนที่แตกต่างกันเพื่อให้มีผลลัพธ์การทดแทนที่แตกต่างกัน ตัวอย่างเช่น [เกม] ถูกแทนที่ด้วย [e-sports] และ [การว่างงาน] จะถูกแทนที่ด้วย [การจ้างงานที่ยืดหยุ่น]
เป็นที่ยอมรับว่ามันโอเคที่จะใช้การเปลี่ยนสตริงเป็นประจำ แต่ประสิทธิภาพเฉลี่ย
ตัวอย่างการใช้งาน:
/**
* 自定替换策略
* @since 0.2.0
*/
@ Test
public void defineReplaceTest () {
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
ISensitiveWordReplace replace = new MySensitiveWordReplace ();
String result = SensitiveWordHelper . replace ( text , replace );
Assert . assertEquals ( "国家旗帜迎风飘扬,教员的画像屹立在***前。" , result );
} ในหมู่พวกเขา MySensitiveWordReplace เป็นนโยบายการเปลี่ยนที่กำหนดเองของเราซึ่งดำเนินการดังนี้:
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 ( '*' );
}
}
}
} เราแก้ไขการแมปสำหรับบางคำและคนอื่น ๆ จะถูกแปลงเป็น * โดยค่าเริ่มต้น
iWordResulthandler สามารถประมวลผลผลลัพธ์ของคำที่ละเอียดอ่อนและอนุญาตให้ผู้ใช้ปรับแต่งได้
ดูคลาสเครื่องมือ WordResultHandlers สำหรับการใช้งานในตัว:
มีเพียงคำที่ละเอียดอ่อนเท่านั้นที่ได้รับการเก็บรักษาไว้
เก็บข้อมูลที่เกี่ยวข้องกับคำที่ละเอียดอ่อนรวมถึงตัวห้อยเริ่มต้นและจุดสิ้นสุดของคำที่ละเอียดอ่อน
ในเวลาเดียวกันคำและข้อมูลฉลากคำที่เกี่ยวข้องจะถูกเก็บไว้
ดู SensitiveWordHelperTest สำหรับกรณีทดสอบทั้งหมด
1) ตัวอย่างพื้นฐาน
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 ()); เราระบุข้อมูลแท็กของคำที่เกี่ยวข้องในไฟล์ 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 ());คุณสมบัติที่ตามมาส่วนใหญ่มุ่งเป้าไปที่การประมวลผลต่าง ๆ ที่กำหนดเป้าหมายสถานการณ์ต่าง ๆ เพื่อปรับปรุงอัตราการเข้าชมของคำที่ละเอียดอ่อนให้มากที่สุด
นี่คือการต่อสู้ที่ยาวนานของความผิดและการป้องกัน
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 );ที่นี่การแปลงรูปแบบทั่วไปของดิจิตอลถูกนำมาใช้
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 ());ข้อมูลส่วนบุคคลเช่นที่อยู่อีเมลไม่ได้เปิดใช้งานโดยค่าเริ่มต้น
final String text = "楼主好人,邮箱 [email protected]" ;
List < String > wordList = SensitiveWordBs . newInstance (). enableEmailCheck ( true ). init (). findAll ( text );
Assert . assertEquals ( "[[email protected]]" , wordList . toString ());โดยทั่วไปจะใช้ในการกรองข้อมูลการโฆษณาเช่นหมายเลขโทรศัพท์มือถือ/QQ และไม่ได้เปิดใช้งานตามค่าเริ่มต้น
หลังจาก v0.2.1 รองรับความยาวที่ตรวจพบโดย numCheckLen(长度)
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 ());ใช้เพื่อกรองข้อมูล URL ทั่วไปไม่ได้เปิดใช้งานโดยค่าเริ่มต้น
v0.18.0 เพิ่มประสิทธิภาพการตรวจจับ URL ซึ่งเข้มงวดมากขึ้นและลดอัตราการตัดสินผิด
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 ));v0.17.0 สนับสนุน
หลีกเลี่ยงผู้ใช้ที่ผ่านการตรวจจับ URL ผ่าน IP ฯลฯ ซึ่งไม่ได้เปิดใช้งานโดยค่าเริ่มต้น
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 ());คุณสมบัติข้างต้นทั้งหมดเปิดใช้งานโดยค่าเริ่มต้นและบางครั้งธุรกิจจำเป็นต้องกำหนดคุณสมบัติการกำหนดค่าที่เกี่ยวข้องอย่างยืดหยุ่น
ดังนั้น V0.0.14 จะเปิดการกำหนดค่าคุณสมบัติ
เพื่อให้ใช้งานที่สง่างามมากขึ้นคำจำกัดความจะถูกใช้อย่างสม่ำเสมอโดย Fluent-API
ผู้ใช้สามารถใช้ SensitiveWordBs เพื่อกำหนดดังนี้:
หมายเหตุ: หลังการกำหนดค่าให้ใช้วัตถุ SensitiveWordBs ที่กำหนดใหม่ของเราแทนวิธีเครื่องมือก่อนหน้า การกำหนดค่าวิธีการเครื่องมือเป็นค่าเริ่มต้นทั้งหมด
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 ));คำอธิบายของการกำหนดค่าแต่ละครั้งมีดังนี้:
| หมายเลขซีเรียล | วิธี | อธิบาย | ค่าเริ่มต้น |
|---|---|---|---|
| 1 | ไม่รู้ | ไม่สนใจเคส | จริง |
| 2 | ไม่รู้ | ไม่สนใจมุมโค้งมนครึ่งมุม | จริง |
| 3 | คนโง่เขลา | ไม่สนใจการเขียนตัวเลข | จริง |
| 4 | ไม่สนใจ chinesestyle | ไม่สนใจรูปแบบการเขียนภาษาจีน | จริง |
| 5 | ไม่สนใจ | ไม่สนใจรูปแบบการเขียนภาษาอังกฤษ | จริง |
| 6 | ไม่รู้ | ละเว้นคำที่ซ้ำกัน | เท็จ |
| 7 | enablenumcheck | ไม่ว่าจะเปิดใช้งานการตรวจจับดิจิตอล | เท็จ |
| 8 | เปิดใช้งาน | เปิดใช้งานการตรวจจับอีเมล | เท็จ |
| 9 | เปิดใช้งาน | ไม่ว่าจะเปิดใช้งานการตรวจจับลิงก์ | เท็จ |
| 10 | enableipv4check | ไม่ว่าจะเปิดใช้งานการตรวจจับ IPv4 | เท็จ |
| 11 | เปิดใช้งานคำว่า | ไม่ว่าจะเปิดใช้งานการตรวจจับคำที่ละเอียดอ่อน | จริง |
| 12 | Numchecklen | การตรวจจับแบบดิจิตอลปรับแต่งความยาวที่ระบุ | 8 |
| 13 | คำพูด | แท็กคำที่สอดคล้องกัน | ไม่มี |
| 14 | มีความชุ่มชื่น | อักขระที่ไม่สนใจ | ไม่มี |
| 15 | WordResultCondition | การประมวลผลเพิ่มเติมสำหรับการจับคู่คำที่ละเอียดอ่อนเช่นการ จำกัด ความจำเป็นในการจับคู่คำภาษาอังกฤษเต็มรูปแบบ | จริงเสมอ |
รองรับ v0.16.1 บางครั้งเราจำเป็นต้องเพิ่มหน่วยความจำซึ่งอาจเป็นดังนี้:
เกี่ยวกับปัญหาการรีไซเคิลหน่วยความจำ
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. init ();
// 后续因为一些原因移除了对应信息,希望释放内存。
wordBs . destroy ();สถานการณ์การใช้งาน: หลังจากการเริ่มต้นเราต้องการเพิ่ม/ลบคำเดียวแทนที่จะปรับเปลี่ยนใหม่อย่างสมบูรณ์ คุณสมบัตินี้จัดทำขึ้นสำหรับสิ่งนี้
เวอร์ชันที่รองรับ: v0.19.0
addWord(word) เพิ่มคำที่ละเอียดอ่อนสนับสนุนคำ/คอลเลกชันเดียว
removeWord(word) ลบคำที่ละเอียดอ่อนรองรับคำ/คอลเลกชันเดียว
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 ());สถานการณ์การใช้งาน: หลังจากการเริ่มต้นเราต้องการเพิ่ม/ลบคำเดียวแทนที่จะปรับเปลี่ยนใหม่อย่างสมบูรณ์ คุณสมบัตินี้จัดทำขึ้นสำหรับสิ่งนี้
เวอร์ชันที่รองรับ: v0.21.0
addWordAllow(word) เพิ่ม whitelist ใหม่รองรับคำ/คอลเลกชันเดียว
removeWordAllow(word) ลบ whitelists รองรับคำ/คอลเลกชันเดียว
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 ());วิธีนี้ ถูกทอดทิ้ง ขอแนะนำให้ใช้วิธีการเพิ่มที่เพิ่มขึ้นด้านบนเพื่อหลีกเลี่ยงการโหลดเต็มรูปแบบ สำหรับความเข้ากันได้วิธีนี้ยังคงอยู่
วิธีการใช้: เมื่อเรียก sensitiveWordBs.init() ให้สร้างคำศัพท์ที่ละเอียดอ่อนขึ้นอยู่กับ iWorddeny+iWordallow เนื่องจากการเริ่มต้นอาจใช้เวลานาน (ระดับที่สอง) การเพิ่มประสิทธิภาพทั้งหมดของ Init จะไม่ส่งผลกระทบต่อฟังก์ชั่นคำศัพท์เก่าเมื่อยังไม่เสร็จสมบูรณ์และใหม่จะต้องเหนือกว่าหลังจากเสร็จสิ้น
@ Component
public class SensitiveWordService {
@ Autowired
private SensitiveWordBs sensitiveWordBs ;
/**
* 更新词库
*
* 每次数据库的信息发生变化之后,首先调用更新数据库敏感词库的方法。
* 如果需要生效,则调用这个方法。
*
* 说明:重新初始化不影响旧的方法使用。初始化完成后,会以新的为准。
*/
public void refresh () {
// 每次数据库的信息发生变化之后,首先调用更新数据库敏感词库的方法,然后调用这个方法。
sensitiveWordBs . init ();
}
} ดังที่ได้กล่าวมาแล้วคุณสามารถกระตุ้นการเริ่มต้นของ sensitiveWordBs.init(); เมื่อพจนานุกรมฐานข้อมูลเปลี่ยนแปลงและฐานข้อมูลจำเป็นต้องมีผล
การใช้งานอื่น ๆ ยังคงเหมือนเดิมโดยไม่ต้องรีสตาร์ทแอป
เวอร์ชันที่รองรับ: v0.13.0
บางครั้งเราอาจต้องการ จำกัด คำพูดที่ละเอียดอ่อนต่อไปเช่นแม้ว่าเราจะกำหนด [av] เป็นคำที่ละเอียดอ่อน แต่เราไม่ต้องการให้ [มี] จับคู่
คุณสามารถปรับแต่งอินเทอร์เฟซ WordResultCondition และใช้นโยบายของคุณเอง
นโยบายในตัวใน WordResultConditions#alwaysTrue() นั้นเป็นจริงเสมอในขณะที่ WordResultConditions#englishWordMatch() ต้องการให้ภาษาอังกฤษต้องตรงกับคำทั้งหมด
คลาสเครื่องมือ WordResultConditions สามารถรับนโยบายการจับคู่ได้
| ทำให้สำเร็จ | อธิบาย | เวอร์ชันที่รองรับ |
|---|---|---|
| เสมอ | จริงเสมอ | |
| ภาษาอังกฤษ | การจับคู่คำภาษาอังกฤษคำเต็มคำ | v0.13.0 |
| คำภาษาอังกฤษ | คำศัพท์ภาษาอังกฤษ/หมายเลขการจับคู่คำเต็มคำ | v0.20.0 |
| คำพูด | ผู้ที่ตอบสนองแท็กเฉพาะเช่นการมุ่งเน้นไปที่แท็ก [โฆษณา] เท่านั้น | v0.23.0 |
| โซ่ (iWordResultCondition ... เงื่อนไข) | สนับสนุนการระบุหลายเงื่อนไขและทำให้พอใจในเวลาเดียวกัน | v0.23.0 |
สถานการณ์เริ่มต้นดั้งเดิม:
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 ());เราสามารถระบุได้ว่าภาษาอังกฤษจะต้องตรงกับคำทั้งหมด
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 ());แน่นอนว่ากลยุทธ์ที่ซับซ้อนมากขึ้นสามารถนำไปใช้ได้ตามต้องการ
เวอร์ชันที่รองรับ: v0.23.0
เราสามารถส่งคืนคำศัพท์ที่ละเอียดอ่อนในเครือด้วยฉลากบางอย่าง
เราได้ระบุสองคำที่ละเอียดอ่อน: ผลิตภัณฑ์, av
MyWordTag คือการใช้แท็กคำที่ละเอียดอ่อนที่เรากำหนด:
/**
* 自定义单词标签
* @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 );
}
}ตัวอย่างเช่นเราจำลองคลาสการใช้งานที่แตกต่างกันสองคลาสแต่ละคลาสมุ่งเน้นไปที่แท็กคำที่แตกต่างกัน
// 只关心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 ());โดยทั่วไปแล้วคำพูดที่ละเอียดอ่อนของเราจะต่อเนื่องมากขึ้นเช่น [หมวกโง่]
จากนั้นก็มีการค้นพบที่ชาญฉลาดว่าคุณสามารถเพิ่มตัวละครบางตัวลงตรงกลางเช่น [โง่ ๆ ! @#$ hat] เพื่อข้ามการตรวจจับ แต่พลังการโจมตีของการสบถจะไม่ลดลง
ดังนั้นจะจัดการกับสถานการณ์ที่คล้ายกันเหล่านี้ได้อย่างไร?
เราสามารถระบุชุดข้ามของอักขระพิเศษและไม่สนใจอักขระที่ไม่มีความหมายเหล่านี้
V0.11.0 เริ่มสนับสนุน
กลยุทธ์อักขระที่สอดคล้องกับ Charignore สามารถกำหนดได้อย่างยืดหยุ่นโดยผู้ใช้
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 ());บางครั้งเราต้องการเพิ่มฉลากลับ ๆ ลงในคำที่ละเอียดอ่อน: เช่นสถานการณ์ทางสังคมความรุนแรง ฯลฯ
ด้วยวิธีนี้คุณลักษณะเพิ่มเติมสามารถทำได้ตามฉลาก ฯลฯ เช่นการประมวลผลเฉพาะบางประเภทของฉลาก
เวอร์ชันที่รองรับ: v0.10.0
คุณสมบัติหลักสนับสนุนเวอร์ชัน: v0.24.0
นี่เป็นเพียงอินเทอร์เฟซนามธรรมและผู้ใช้สามารถกำหนดการนำไปใช้งานได้ด้วยตนเอง ตัวอย่างเช่นจากการสืบค้นฐานข้อมูลการอ่านไฟล์การโทร API ฯลฯ
public interface IWordTag {
/**
* 查询标签列表
* @param word 脏词
* @return 结果
*/
Set < String > getTag ( String word );
} เพื่ออำนวยความสะดวกในการใช้งานในสถานการณ์ส่วนใหญ่กลยุทธ์บางฉากจะถูกนำไปใช้ในคลาส WordTags
| วิธีการดำเนินการ | อธิบาย | คำพูด |
|---|---|---|
| ไม่มี() | การใช้งานที่ว่างเปล่า | v0.10.0 สนับสนุน |
| ไฟล์ (สตริง filepath) | ระบุเส้นทางไฟล์ | v0.10.0 สนับสนุน |
| ไฟล์ (String FilePath, String WordsPlit, String tagsplit) | ระบุเส้นทางไฟล์รวมถึงตัวคั่นคำและตัวคั่นแท็ก | v0.10.0 สนับสนุน |
| แผนที่ (แผนที่สุดท้าย <String, Set> WordTagMap) | การเริ่มต้นตามแผนที่ | การสนับสนุน v0.24.0 |
| เส้น (สายการรวบรวม) | รายการสตริง | การสนับสนุน v0.24.0 |
| บรรทัด (บรรทัดคอลเลกชัน, สตริง WordsPlit, String tagspli) | รายการสตริงรวมถึงตัวแยกคำและตัวคั่นฉลาก | การสนับสนุน v0.24.0 |
| ระบบ() | การใช้งานไฟล์ระบบในตัวรวมการจำแนกประเภทเครือข่าย | การสนับสนุน v0.24.0 |
| ค่าเริ่มต้น () | นโยบายเริ่มต้นคือระบบปัจจุบัน | การสนับสนุน v0.24.0 |
| โซ่ (iwordtag ... อื่น ๆ ) | วิธีลูกโซ่รองรับการรวมผู้ใช้เพื่อใช้หลายนโยบาย | การสนับสนุน v0.24.0 |
รูปแบบของแท็กคำที่ละเอียดอ่อนเราเริ่มต้นเป็น敏感词tag1,tag2 ซึ่งหมายความว่าแท็กของ敏感词คือ tag1 และ tag2
ตัวอย่างเช่น
五星红旗 政治,国家
นอกจากนี้ยังแนะนำสำหรับเนื้อหาบรรทัดไฟล์ทั้งหมดและเนื้อหาสตริงที่ระบุ หากไม่พอใจเพียงแค่ใช้มันในลักษณะที่กำหนดเอง
เริ่มต้นด้วย v0.24.0 แท็กคำเริ่มต้นคือ WordTags.system()
หมายเหตุ: ปัจจุบันสถิติข้อมูลมาจากอินเทอร์เน็ตและมีการละเว้นมากมาย ทุกคนยินดีที่จะแก้ไขปัญหาและปรับปรุงต่อไป ...
SensitiveWordBs sensitiveWordBs = SensitiveWordBs . newInstance ()
. wordTag ( WordTags . system ())
. init ();
Set < String > tagSet = sensitiveWordBs . tags ( "博彩" );
Assert . assertEquals ( "[3]" , tagSet . toString ());ที่นี่เพื่อเพิ่มประสิทธิภาพขนาดการบีบอัดหมวดหมู่ที่เกี่ยวข้องจะถูกแสดงเป็นตัวเลข
รายการความหมายของตัวเลขมีดังนี้:
0 政治
1 毒品
2 色情
3 赌博
4 违法
ที่นี่เราใช้ไฟล์เป็นตัวอย่างเพื่อสาธิตวิธีการใช้งาน
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 ()); โดยที่ dict_tag_test.txt เนื้อหาที่กำหนดเองของเรามีดังนี้:
零售 广告,网络
เมื่อเราได้รับคำที่ละเอียดอ่อนเราสามารถตั้งค่ากลยุทธ์การประมวลผลผลลัพธ์ที่สอดคล้องกันเพื่อให้ได้ข้อมูลแท็กคำที่ละเอียดอ่อนที่สอดคล้องกัน
// 自定义测试标签类
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 ()); เราปรับแต่งแท็กสำหรับคำหลักของ天安门จากนั้นระบุว่ากลยุทธ์การประมวลผลผลลัพธ์ของ FindAll คือ WordResultHandlers.wordTags() และเราสามารถรับรายการแท็กที่เกี่ยวข้องในขณะที่ได้รับคำที่ละเอียดอ่อน
บางครั้งเราต้องการออกแบบการโหลดคำที่ละเอียดอ่อนลงในไดนามิกเช่นการปรับเปลี่ยนคอนโซลซึ่งสามารถมีผลในเวลาจริง
V0.0.13 รองรับคุณสมบัตินี้
ในการใช้คุณสมบัตินี้และเข้ากันได้กับฟังก์ชั่นก่อนหน้านี้เราได้กำหนดอินเทอร์เฟซสองแบบ
อินเทอร์เฟซมีดังนี้คุณสามารถปรับแต่งการใช้งานของคุณเอง
รายการที่ส่งคืนหมายความว่าคำนั้นเป็นคำที่ละเอียดอ่อน
/**
* 拒绝出现的数据-返回的内容被当做是敏感词
* @author binbin.hou
* @since 0.0.13
*/
public interface IWordDeny {
/**
* 获取结果
* @return 结果
* @since 0.0.13
*/
List < String > deny ();
}ตัวอย่างเช่น:
public class MyWordDeny implements IWordDeny {
@ Override
public List < String > deny () {
return Arrays . asList ( "我的自定义敏感词" );
}
}อินเทอร์เฟซมีดังนี้คุณสามารถปรับแต่งการใช้งานของคุณเอง
รายการที่ส่งคืนหมายความว่าคำนั้นไม่ใช่คำที่ละเอียดอ่อน
/**
* 允许的内容-返回的内容不被当做敏感词
* @author binbin.hou
* @since 0.0.13
*/
public interface IWordAllow {
/**
* 获取结果
* @return 结果
* @since 0.0.13
*/
List < String > allow ();
}ชอบ:
public class MyWordAllow implements IWordAllow {
@ Override
public List < String > allow () {
return Arrays . asList ( "五星红旗" );
}
}หลังจากที่อินเทอร์เฟซได้รับการปรับแต่งแน่นอนจะต้องมีการระบุให้มีผล
เพื่อให้ใช้งานที่สง่างามยิ่งขึ้นเราได้ออกแบบ SensitiveWordBs Boot Class
คุณสามารถระบุคำที่ละเอียดอ่อนผ่าน WordDeny (), wordallow () ระบุคำที่ไม่ไวต่อความรู้สึกและเริ่มต้นพจนานุกรมคำศัพท์ที่ละเอียดอ่อนผ่าน init ()
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. wordDeny ( WordDenys . defaults ())
. wordAllow ( WordAllows . defaults ())
. init ();
final String text = "五星红旗迎风飘扬,毛主席的画像屹立在天安门前。" ;
Assert . assertTrue ( wordBs . contains ( text ));หมายเหตุ: init () ใช้เวลานานในการสร้างคำที่ละเอียดอ่อน DFA โดยทั่วไปแนะนำว่า จะเริ่มต้นเพียงครั้งเดียว เมื่อใช้การเริ่มต้น แทนที่จะเริ่มต้นทำซ้ำ!
เราสามารถทดสอบการใช้งานที่กำหนดเองดังนี้:
String text = "这是一个测试,我的自定义敏感词。" ;
SensitiveWordBs wordBs = SensitiveWordBs . newInstance ()
. wordDeny ( new MyWordDeny ())
. wordAllow ( new MyWordAllow ())
. init ();
Assert . assertEquals ( "[我的自定义敏感词]" , wordBs . findAll ( text ). toString ()); นี่คือคำเดียวที่我的自定义敏感词เป็นคำที่ละเอียดอ่อนและ测试ไม่ใช่คำที่ละเอียดอ่อน
แน่นอนนี่คือการใช้งานที่กำหนดเองทั้งหมดของเรา โดยทั่วไปขอแนะนำให้ใช้การกำหนดค่าเริ่มต้น + การกำหนดค่าที่กำหนดเองของระบบ
สามารถใช้วิธีการต่อไปนี้ได้
Method WordDenys.chains() รวมการใช้งานหลายอย่างเข้ากับ iWorddeny เดียวกัน
Method WordAllows.chains() รวมการใช้งานหลายอย่างเข้ากับ iWordallow เดียวกัน
ตัวอย่าง:
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 ());ทั้งหมดใช้การกำหนดค่าเริ่มต้นของระบบและการกำหนดค่าที่กำหนดเองในเวลาเดียวกัน
หมายเหตุ: เราเริ่มต้น WordBs ใหม่ดังนั้นใช้ WordBs ใหม่เพื่อตัดสิน แทนที่จะใช้วิธีเครื่องมือ SensitiveWordHelper ก่อนหน้าการกำหนดค่าวิธีการเครื่องมือเป็นค่าเริ่มต้น!
ในการใช้งานจริงตัวอย่างเช่นคุณสามารถแก้ไขการกำหนดค่าหน้าและจากนั้นมีผลในเวลาจริง
ข้อมูลถูกเก็บไว้ในฐานข้อมูล ต่อไปนี้เป็นตัวอย่างของรหัสหลอก คุณสามารถอ้างถึง SpringsensitiveitiveWordConfig.java
จำเป็นเวอร์ชัน v0.0.15 ขึ้นไป
รหัสหลอกแบบง่าย ๆ มีดังนี้และแหล่งที่มาของข้อมูลเป็นฐานข้อมูล
MyDDWOWEROLD และ MYDDWOWDDENY เป็นคลาสการใช้งานที่กำหนดเองตามฐานข้อมูลเป็นแหล่งที่มา
@ 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 ;
}
}การเริ่มต้นคำศัพท์ที่ละเอียดอ่อนนั้นใช้เวลานานดังนั้นจึงขอแนะนำให้ทำการเริ่มต้นเริ่มต้นครั้งแรกเมื่อโปรแกรมเริ่มต้น
หลังจาก v0.6.0 ให้เพิ่มการทดสอบมาตรฐานที่สอดคล้องกัน
BenchMarkTimestest
สภาพแวดล้อมการทดสอบเป็นสมุดบันทึกปกติ:
处理器 12th Gen Intel(R) Core(TM) i7-1260P 2.10 GHz
机带 RAM 16.0 GB (15.7 GB 可用)
系统类型 64 位操作系统, 基于 x64 的处理器
PS: สภาพแวดล้อมที่แตกต่างกันจะแตกต่างกันไป แต่สัดส่วนนั้นมีความเสถียร
ข้อมูลทดสอบ: 100+ สตริง, ลูป 10W ครั้ง
| หมายเลขซีเรียล | ฉาก | ใช้เวลานาน | คำพูด |
|---|---|---|---|
| 1 | ใช้คำที่ละเอียดอ่อนโดยไม่มีการแปลงรูปแบบใด ๆ | 1470ms ประมาณ 7.2W QPS | การติดตามประสิทธิภาพที่รุนแรงคุณสามารถกำหนดค่าได้เช่นนี้ |
| 2 | ใช้คำที่ละเอียดอ่อนรองรับการแปลงรูปแบบทั้งหมด | 2744ms ประมาณ 3.7W QPS | พบกับสถานการณ์ส่วนใหญ่ |
ลบคำที่ละเอียดอ่อนออกจากอักขระภาษาจีนแต่ละตัว ในประเทศจีนวลีควรได้รับการพิจารณาว่าเป็นคำเดียวเพื่อลดอัตราการตัดสินที่ผิดพลาด
สนับสนุนการเปลี่ยนแปลงคำที่ละเอียดอ่อนของแต่ละบุคคล?
ลบเพิ่มแก้ไข?
การรองรับอินเตอร์เฟสแท็กคำที่ละเอียดอ่อน
การสนับสนุนแท็กเมื่อประมวลผลคำที่ละเอียดอ่อน
การเปรียบเทียบการใช้หน่วยความจำ + การเพิ่มประสิทธิภาพของ WordData
ผู้ใช้ระบุวลีที่กำหนดเองและอนุญาตให้มีการรวมวลีที่ระบุไว้ทำให้มีความยืดหยุ่นมากขึ้น
นโยบายการรวมกันของ Formatcombine/Checkcombine/Allowdenycombine ช่วยให้ผู้ใช้ปรับแต่งได้
การเพิ่มประสิทธิภาพของกลยุทธ์การตรวจสอบคำศัพท์การแปลงแบบ Unified Traversal +
เพิ่ม threadlocal และการเพิ่มประสิทธิภาพประสิทธิภาพอื่น ๆ
คำศัพท์ที่ไวต่อคำศัพท์ที่ละเอียดอ่อน V1.2.0 โอเพ่นซอร์ส
วิธีการสนับสนุนการปรับใช้แบบกระจายในการเปิดตัวที่ละเอียดอ่อน-Admin v1.3.0?
01-beginner ของเครื่องมือคำที่อ่อนไหวของโอเพ่นซอร์ส
02-5- จะใช้เครื่องมือ Word ที่ละเอียดอ่อนหรือไม่? ชี้แจงแนวคิดของการใช้คำที่ต้องห้าม
03-support คำหยุดคำหยุดการเพิ่มประสิทธิภาพคำและสัญลักษณ์พิเศษ
04 พจนานุกรมของคำศัพท์ที่ละเอียดอ่อนลดขนาดลง
05 คำอธิบายรายละเอียดของอัลกอริทึม DFA ของคำที่ละเอียดอ่อน (อัลกอริทึม Trie Tree)
คำที่ไวต่อความรู้สึก 06 (คำสกปรก) จะเพิกเฉยต่อตัวละครที่ไม่มีความหมายได้อย่างไร? บรรลุผลการกรองที่ดีขึ้น
v0.10.0 การสนับสนุนที่สำคัญสำหรับแท็กการจำแนกประเภทคำสกปรก
v0.11.0 - คุณสมบัติใหม่ของคำที่ละเอียดอ่อน: ละเว้นอักขระที่ไม่มีความหมาย, พจนานุกรมแท็กคำ
V0.12.0 ความสามารถในการติดฉลากคำศัพท์ที่ไวต่อคำ/คำศัพท์สกปรกได้รับการปรับปรุงเพิ่มเติม
V0.13.0 ฟีเจอร์ไวรัสที่ไวต่อการเปิดตัวรองรับการจับคู่คำเต็มคำในคำภาษาอังกฤษ
v0.16.1 การเปิดตัวทรัพยากรหน่วยความจำในการปล่อยคุณสมบัติใหม่ของคำศัพท์ที่ละเอียดอ่อน
V0.19.0 - คำที่ละเอียดอ่อนพร้อมคุณสมบัติใหม่ของคำที่ละเอียดอ่อนที่แก้ไขเป็นรายบุคคลโดยไม่ต้องเริ่มต้นซ้ำ
v0.20.0 ลักษณะใหม่ของคำที่ละเอียดอ่อนตรงกับตัวเลขทั้งหมดไม่ใช่การจับคู่บางส่วน
v0.21.0 ผู้ทำรายการที่มีคุณสมบัติใหม่ของคำศัพท์ที่ละเอียดอ่อนรองรับการแก้ไขเดี่ยวแก้ไขปัญหาเมื่อ Whitelists มีบัญชีดำ
พินอินเป็นพินอิน
Pinyin2hanzi Pinyin กับตัวละครจีน
แบ่งส่วนการแบ่งส่วนคำภาษาจีนประสิทธิภาพสูง
OpenCC4J จีนดั้งเดิมที่เปลี่ยนรูปแบบภาษาจีนแบบดั้งเดิมของจีน
ความคล้ายคลึงกันของตัวละครภาษาจีน NLP-Hanzi-Similar
การตรวจจับการสะกดคำ
คำที่ละเอียดอ่อนคำที่ละเอียดอ่อน