Este módulo é baseado na modificação mágica de segmento de nó, adiciona suporte de elétrons e navegador e está pronto para ser otimizado para o ambiente de corrida com vários threads de elétrons.
A razão pela qual precisamos gastar tempo para modificar é que, embora segment e nodejieba sejam muito úteis em ambientes de nós, eles não podem ser executados em ambientes de navegador e elétrons. Eu refatorei o código no ES2015 e inlinei o arquivo de dicionário com o plug -in Babel. O tamanho é de 3,8m se for carregado. No entanto, se você não precisar de alguns dicionários, o dicionário e os módulos suportam agitação de árvores (use o módulo 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 ) ;Para o ambiente Runkit:
const { Segment , useDefault } = require ( 'segmentit' ) ;
const segmentit = useDefault ( new Segment ( ) ) ;
const result = segmentit . doSegment ( '工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作。' ) ;
console . log ( result ) ;Teste gratuito no Runkit
Exemplos de uso direto do navegador:
Primeiro, cite "https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/segment.js"
const segmentit = Segmentit . useDefault ( new Segmentit . Segment ( ) ) ;
const result = segmentit . doSegment ( '工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作。' ) ;
console . log ( result ) ; (De fato, é apenas para adicionar Segmentit. a todas as chamadas, inicialização e outras coisas)
Tags da categoria de palavras no estilo de gagueira:
// 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>"] A implementação específica do usedefault é a seguinte:
// 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 ) ; Assim, você pode realmente importar a parte necessária do dicionário e os módulos e depois baixá -los um por um. Esses dicionários e módulos sem importação devem ser removidos pelo tremor de árvores de Webpack. Você também pode carregar seu próprio arquivo de dicionário definido dessa maneira, apenas precisa da assinatura da função do principal dict para ser (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 ) ;O dicionário de Pangu é relativamente retrô, e não há palavras como "loli suave e fofo". Por favor, PR pelo seu próprio vocabulário.
O Tokenizer é um middleware que precisa ser passado ao passar por palavras. Semelhante ao middleware do Redux, sua função dividida aceita uma matriz de token com metade do particípio e retorna uma matriz de token do mesmo formato (é por isso que não deve ser participado com palavras de texto muito longas, caso contrário, essa matriz será enorme).
Exemplos são os seguintes:
// @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' ) ;
// ...
}O otimizador é um local onde as regras heurísticas podem ser colocadas após o término da palavra particípio e verifica -se que é difícil usar o processamento do dicionário, mas quando pode ser processado com regras heurísticas, pode colocar essas regras heurísticas. Sua função DoOptimize também recebe uma matriz de token e retorna uma matriz de token do mesmo formato.
Além da matriz de token, você também pode personalizar os parâmetros restantes. Por exemplo, no exemplo a seguir, nos chamaremos recursivamente uma vez e julgaremos a profundidade recursiva através do segundo parâmetro:
// @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 ) ;
}Por exemplo, todos os tipos de ferramentas de segmentação de palavras não podem corresponder ao vermelho em "parte da calcinha vermelha" com a parte do discurso, mas no segmentit eu adicionei um simples adjetivo para lidar com isso:
// @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 licenciado