Ce module est basé sur la modification de la magie du segment du nœud, ajoute une prise en charge des électrons et du navigateur et est prêt à être optimisé pour un environnement de course multi-thread électronique.
La raison pour laquelle nous devons passer du temps à modifier est que bien que segment et nodejieba soient très utiles dans les environnements nœuds, ils ne peuvent pas du tout fonctionner dans les environnements du navigateur et des électrons. J'ai refactorisé le code à ES2015 et j'ai incliné le fichier du dictionnaire avec le plugin Babel. La taille est de 3,8 m si elle est chargée. Cependant, si vous n'avez pas besoin de dictionnaires, le dictionnaire et les modules prennent en charge les tremblements d'arbre (veuillez utiliser le module ESM).
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/segmentit.min.js " /> npm i segmentit import { Segment , useDefault } from 'segmentit' ;
const segmentit = useDefault ( new Segment ( ) ) ;
const result = segmentit . doSegment ( '工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作。' ) ;
console . log ( result ) ;Pour l'environnement Runkit:
const { Segment , useDefault } = require ( 'segmentit' ) ;
const segmentit = useDefault ( new Segment ( ) ) ;
const result = segmentit . doSegment ( '工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作。' ) ;
console . log ( result ) ;Essai gratuit sur Runkit
Exemples d'utilisation directe du navigateur:
Tout d'abord, veuillez citer "https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/segmentit.js"
const segmentit = Segmentit . useDefault ( new Segmentit . Segment ( ) ) ;
const result = segmentit . doSegment ( '工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作。' ) ;
console . log ( result ) ; (En fait, c'est juste pour ajouter Segmentit. à tous les appels, initialisation et autres choses)
Tags de catégorie de mots dans le style bégayant:
// import Segment, { useDefault, cnPOSTag, enPOSTag } from 'segmentit';
const { Segment , useDefault , cnPOSTag , enPOSTag } = require ( 'segmentit' ) ;
const segmentit = useDefault ( new Segment ( ) ) ;
console . log ( segmentit . doSegment ( '一人得道,鸡犬升天' ) . map ( i => ` ${ i . w } < ${ cnPOSTag ( i . p ) } > < ${ enPOSTag ( i . p ) } >` ) )
// ↑ ["一人得道 <习语,数词 数语素> <l,m>", ", <标点符号> <w>", "鸡犬升天 <成语> <i>"] La mise en œuvre spécifique de UsedFault est la suivante:
// useDefault
import { Segment , modules , dicts , synonyms , stopwords } from 'segmentit' ;
const segmentit = new Segment ( ) ;
segmentit . use ( modules ) ;
segmentit . loadDict ( dicts ) ;
segmentit . loadSynonymDict ( synonyms ) ;
segmentit . loadStopwordDict ( stopwords ) ; Vous pouvez donc réellement importer la partie requise du dictionnaire et des modules, puis les télécharger un par un. Ces dictionnaires et modules sans importation doivent être supprimés par le tremblement d'arbre de WebPack. Vous pouvez également charger votre propre fichier de dictionnaire défini de cette manière, il suffit de la signature de la fonction de la charge principale pour être (dicts: string | string[]): Segment .
// load custom module and dicts
import {
Segment ,
ChsNameTokenizer ,
DictOptimizer ,
EmailOptimizer ,
PunctuationTokenizer ,
URLTokenizer ,
ChsNameOptimizer ,
DatetimeOptimizer ,
DictTokenizer ,
ForeignTokenizer ,
SingleTokenizer ,
WildcardTokenizer ,
pangu ,
panguExtend1 ,
panguExtend2 ,
names ,
wildcard ,
synonym ,
stopword ,
} from 'segmentit' ;
const segmentit = new Segment ( ) ;
// load them one by one, or by array
segmentit . use ( ChsNameTokenizer ) ;
segmentit . loadDict ( pangu ) ;
segmentit . loadDict ( [ panguExtend1 , panguExtend2 ] ) ;
segmentit . loadSynonymDict ( synonym ) ;
segmentit . loadStopwordDict ( stopword ) ;Le dictionnaire de Pangu est relativement rétro, et il n'y a pas de mots comme «loli doux et mignon». S'il vous plaît PR pour votre propre vocabulaire.
Tokenizer est un middleware qui doit être passé lors de la participation aux mots. Semblable au middleware de Redux, sa fonction divisée accepte un tableau de jeton avec la moitié du participe et renvoie un tableau de jeton du même format (c'est pourquoi il ne devrait pas participer à des mots de texte trop longs, sinon ce tableau sera énorme).
Les exemples sont les suivants:
// @flow
import { Tokenizer } from 'segmentit' ;
import type { SegmentToken , TokenStartPosition } from 'segmentit' ;
export default class ChsNameTokenizer extends Tokenizer {
split ( words : Array < SegmentToken > ) : Array < SegmentToken > {
// 可以获取到 this.segment 里的各种信息
const POSTAG = this . segment . POSTAG ;
const TABLE = this . segment . getDict ( 'TABLE' ) ;
// ...
}Optimizer est un endroit où les règles heuristiques peuvent être placées une fois le mot participe terminé et il est constaté qu'il est difficile d'utiliser le traitement du dictionnaire, mais lorsqu'il peut être traité avec des règles heuristiques, elle peut placer ces règles heuristiques. Sa fonction DOOPtimize reçoit également un tableau de jeton et renvoie un tableau de jeton du même format.
En plus du tableau de jeton, vous pouvez également personnaliser les paramètres restants. Par exemple, dans l'exemple suivant, nous nous appellerons une fois récursivement et jugerons la profondeur récursive par le deuxième paramètre:
// @flow
import { Optimizer } from './BaseModule' ;
import type { SegmentToken } from './type' ;
export default class DictOptimizer extends Optimizer {
doOptimize ( words : Array < SegmentToken > , isNotFirst : boolean ) : Array < SegmentToken > {
// 可以获取到 this.segment 里的各种信息
const POSTAG = this . segment . POSTAG ;
const TABLE = this . segment . getDict ( 'TABLE' ) ;
// ...
// 针对组合数字后无法识别新组合的数字问题,需要重新扫描一次
return isNotFirst === true ? words : this . doOptimize ( words , true ) ;
}Par exemple, toutes sortes d'outils de segmentation des mots ne peuvent pas correspondre au rouge dans "partie de la culotte rouge" avec la partie de la parole, mais dans segmentit, j'ai ajouté un adjectifoptimizer simple pour le gérer:
// @flow
// https://github.com/linonetwo/segmentit/blob/master/src/module/AdjectiveOptimizer.js
import { Optimizer } from './BaseModule' ;
import type { SegmentToken } from './type' ;
import { colors } from './COLORS' ;
// 把一些错认为名词的词标注为形容词,或者对名词作定语的情况
export default class AdjectiveOptimizer extends Optimizer {
doOptimize ( words : Array < SegmentToken > ) : Array < SegmentToken > {
const { POSTAG } = this . segment ;
let index = 0 ;
while ( index < words . length ) {
const word = words [ index ] ;
const nextword = words [ index + 1 ] ;
if ( nextword ) {
// 对于<颜色>+<的>,直接判断颜色是形容词(字典里颜色都是名词)
if ( nextword . p === POSTAG . D_U && colors . includes ( word . w ) ) {
word . p = POSTAG . D_A ;
}
// 如果是连续的两个名词,前一个是颜色,那这个颜色也是形容词
if ( word . p === POSTAG . D_N && nextword . p === POSTAG . D_N && colors . includes ( word . w ) ) {
word . p = POSTAG . D_A ;
}
}
// 移到下一个单词
index += 1 ;
}
return words ;
}
} MIT sous licence