natural 6.12.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +2 -1
- package/.eslintrc.json +13 -0
- package/.github/workflows/node.js.yml +3 -6
- package/lib/natural/analyzers/SenType.ts +30 -0
- package/lib/natural/analyzers/index.d.ts +6 -10
- package/lib/natural/brill_pos_tagger/index.d.ts +23 -14
- package/lib/natural/brill_pos_tagger/index.js +1 -1
- package/lib/natural/classifiers/bayes_classifier.js +1 -1
- package/lib/natural/classifiers/classifier.js +11 -34
- package/lib/natural/classifiers/classifier_train_parallel.js +7 -5
- package/lib/natural/classifiers/index.d.ts +36 -15
- package/lib/natural/classifiers/maxent/Classifier.js +5 -3
- package/lib/natural/distance/index.d.ts +11 -14
- package/lib/natural/inflectors/count_inflector.js +18 -21
- package/lib/natural/inflectors/fr/count_inflector.js +18 -19
- package/lib/natural/inflectors/index.d.ts +12 -3
- package/lib/natural/inflectors/index.js +3 -0
- package/lib/natural/ngrams/index.d.ts +5 -5
- package/lib/natural/normalizers/index.d.ts +24 -1
- package/lib/natural/normalizers/index.js +4 -1
- package/lib/natural/normalizers/normalizer_ja.js +109 -72
- package/lib/natural/phonetics/dm_soundex.js +52 -51
- package/lib/natural/phonetics/double_metaphone.js +397 -399
- package/lib/natural/phonetics/index.d.ts +42 -12
- package/lib/natural/phonetics/metaphone.js +134 -157
- package/lib/natural/phonetics/phonetic.js +5 -29
- package/lib/natural/phonetics/soundex.js +45 -54
- package/lib/natural/sentiment/index.d.ts +6 -6
- package/lib/natural/spellcheck/index.d.ts +2 -0
- package/lib/natural/stemmers/index.d.ts +43 -1
- package/lib/natural/stemmers/index.js +1 -0
- package/lib/natural/stemmers/token.js +131 -132
- package/lib/natural/tfidf/index.d.ts +7 -7
- package/lib/natural/tfidf/tfidf.js +7 -1
- package/lib/natural/tokenizers/index.d.ts +2 -2
- package/lib/natural/trie/index.d.ts +1 -1
- package/lib/natural/util/index.d.ts +8 -0
- package/lib/natural/util/index.js +2 -0
- package/lib/natural/util/storage/index.d.ts +39 -0
- package/lib/natural/util/storage/index.js +24 -0
- package/package.json +22 -9
- package/ts_spec/MaxEntClassifier_spec.ts +130 -0
- package/ts_spec/SentimentAnalyzer_spec.ts +232 -0
- package/ts_spec/WordPunctTokenizer_spec.ts +57 -0
- package/ts_spec/aggressive_tokenizer_de_spec.ts +36 -0
- package/ts_spec/aggressive_tokenizer_es_spec.ts +39 -0
- package/ts_spec/aggressive_tokenizer_fr_spec.ts +111 -0
- package/ts_spec/aggressive_tokenizer_hi_spec.ts +70 -0
- package/ts_spec/aggressive_tokenizer_nl_spec.ts +39 -0
- package/ts_spec/aggressive_tokenizer_pt_spec.ts +48 -0
- package/ts_spec/aggressive_tokenizer_spec.ts +57 -0
- package/ts_spec/aggressive_tokenizer_sv_spec.ts +52 -0
- package/ts_spec/aggressive_tokenizer_vi_spec.ts +48 -0
- package/ts_spec/bayes_classifier_spec.ts +165 -0
- package/ts_spec/brill_pos_tagger_spec.ts +79 -0
- package/ts_spec/brill_pos_trainer_spec.ts +107 -0
- package/ts_spec/carry_stemmer_fr_spec.ts +97 -0
- package/ts_spec/classifier_spec.ts +104 -0
- package/ts_spec/count_inflector_fr_spec.ts +47 -0
- package/ts_spec/count_inflector_spec.ts +76 -0
- package/ts_spec/damerau_levenshtein_spec.ts +53 -0
- package/ts_spec/dice_coefficient_spec.ts +37 -0
- package/ts_spec/double_metaphone_spec.ts +739 -0
- package/ts_spec/hamming_distance_spec.ts +66 -0
- package/ts_spec/jaro-winkler_spec.ts +79 -0
- package/ts_spec/lancaster_stemmer_spec.ts +63 -0
- package/ts_spec/levenshtein_spec.ts +107 -0
- package/ts_spec/logistic_regression_classifier_spec.ts +93 -0
- package/ts_spec/longest_path_tree_spec.ts +111 -0
- package/ts_spec/metaphone_spec.ts +258 -0
- package/ts_spec/ngram_spec.ts +145 -0
- package/ts_spec/ngram_zh_spec.ts +124 -0
- package/ts_spec/normalizer_ja_spec.ts +165 -0
- package/ts_spec/normalizer_no_spec.ts +112 -0
- package/ts_spec/normalizer_spec.ts +141 -0
- package/ts_spec/noun_inflector_fr_spec.ts +472 -0
- package/ts_spec/noun_inflector_ja_spec.ts +116 -0
- package/ts_spec/noun_inflector_spec.ts +369 -0
- package/ts_spec/orthography_tokenizer_spec.ts +47 -0
- package/ts_spec/porter_stemmer_de_spec.ts +53 -0
- package/ts_spec/porter_stemmer_es_spec.ts +63 -0
- package/ts_spec/porter_stemmer_fr_spec.ts +103 -0
- package/ts_spec/porter_stemmer_it_spec.ts +56 -0
- package/ts_spec/porter_stemmer_nl_spec.ts +73 -0
- package/ts_spec/porter_stemmer_no_spec.ts +148 -0
- package/ts_spec/porter_stemmer_pt_spec.ts +50 -0
- package/ts_spec/porter_stemmer_ru_spec.ts +67 -0
- package/ts_spec/porter_stemmer_spec.ts +202 -0
- package/ts_spec/porter_stemmer_sv_spec.ts +41 -0
- package/ts_spec/present_verb_inflector_spec.ts +127 -0
- package/ts_spec/remove_diacritics_spec.ts +30 -0
- package/ts_spec/sentence_analyzer_spec.ts +293 -0
- package/ts_spec/sentence_tokenizer_parser_spec.ts +200 -0
- package/ts_spec/sentence_tokenizer_spec.ts +189 -0
- package/ts_spec/shortest_path_tree_spec.ts +141 -0
- package/ts_spec/soundex_spec.ts +162 -0
- package/ts_spec/spellcheck_spec.ts +112 -0
- package/ts_spec/stemmer_id_spec.ts +374 -0
- package/ts_spec/stemmer_ja_spec.ts +69 -0
- package/ts_spec/stemmer_token_spec.ts +163 -0
- package/ts_spec/tfidf_spec.ts +275 -0
- package/ts_spec/tokenizer_case_spec.ts +242 -0
- package/ts_spec/tokenizer_ja_spec.ts +63 -0
- package/ts_spec/transliterator_ja_spec.ts +105 -0
- package/ts_spec/treebank_word_tokenizer_spec.ts +38 -0
- package/ts_spec/trie_spec.ts +197 -0
- package/tsconfig.json +5 -3
- package/example.txt +0 -1
|
@@ -38,27 +38,26 @@ THE SOFTWARE.
|
|
|
38
38
|
* * CountInflector(2, undefined, undefined, ALTERNATIVE); // "2nd"
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
class CountInflectorFr {
|
|
42
|
+
/**
|
|
43
|
+
* @param {number|string} i
|
|
44
|
+
* @return {string}
|
|
45
|
+
*/
|
|
46
|
+
nth (i) {
|
|
47
|
+
return i.toString() + this.nthForm(i)
|
|
48
|
+
}
|
|
43
49
|
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @param {number|string} i
|
|
52
|
+
* @return {string}
|
|
53
|
+
*/
|
|
54
|
+
nthForm (i) {
|
|
55
|
+
if (i === 1 || i === 'I') {
|
|
56
|
+
return 'er'
|
|
57
|
+
}
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
* @param {number|string} i
|
|
54
|
-
* @return {string}
|
|
55
|
-
*/
|
|
56
|
-
function nthForm (i) {
|
|
57
|
-
if (i === 1 || i === 'I') {
|
|
58
|
-
return 'er'
|
|
59
|
+
return 'e'
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
-
return 'e'
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
module.exports =
|
|
63
|
+
module.exports = CountInflectorFr
|
|
@@ -20,7 +20,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
20
20
|
THE SOFTWARE.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
export class
|
|
23
|
+
export class SingularPluralInflector {
|
|
24
|
+
singularize (token: string): string
|
|
25
|
+
pluralize (token: string): string
|
|
26
|
+
addSingular (pattern: RegExp, replacement: string): void
|
|
27
|
+
addPlural (pattern: RegExp, replacement: string): void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class NounInflector extends SingularPluralInflector {
|
|
24
31
|
pluralize (token: string): string
|
|
25
32
|
singularize (token: string): string
|
|
26
33
|
}
|
|
@@ -28,10 +35,12 @@ export class NounInflector {
|
|
|
28
35
|
export class NounInflectorFr extends NounInflector {}
|
|
29
36
|
export class NounInflectorJa extends NounInflector {}
|
|
30
37
|
|
|
31
|
-
export
|
|
32
|
-
nth: (i: number) => string
|
|
38
|
+
export class CountInflector {
|
|
39
|
+
nth: (i: number | string) => string
|
|
33
40
|
}
|
|
34
41
|
|
|
42
|
+
export class CountInflectorFr extends CountInflector {}
|
|
43
|
+
|
|
35
44
|
export class PresentVerbInflector {
|
|
36
45
|
pluralize (token: string): string
|
|
37
46
|
singularize (token: string): string
|
|
@@ -25,5 +25,8 @@ THE SOFTWARE.
|
|
|
25
25
|
exports.NounInflector = require('./noun_inflector')
|
|
26
26
|
exports.NounInflectorFr = require('./fr/noun_inflector')
|
|
27
27
|
exports.NounInflectorJa = require('./ja/noun_inflector')
|
|
28
|
+
|
|
28
29
|
exports.PresentVerbInflector = require('./present_verb_inflector')
|
|
30
|
+
|
|
29
31
|
exports.CountInflector = require('./count_inflector')
|
|
32
|
+
exports.CountInflectorFr = require('./fr/count_inflector')
|
|
@@ -22,12 +22,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
22
22
|
THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import { Tokenizer } from '../tokenizers'
|
|
25
|
+
import type { Tokenizer } from '../tokenizers'
|
|
26
26
|
|
|
27
27
|
declare interface NGramsStats {
|
|
28
28
|
ngrams: string[][]
|
|
29
|
-
frequencies:
|
|
30
|
-
Nr:
|
|
29
|
+
frequencies: Record<string, number>
|
|
30
|
+
Nr: Record<number, number>
|
|
31
31
|
numberOfNgrams: number
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -36,8 +36,8 @@ declare interface NGramsFunctions {
|
|
|
36
36
|
// value, method signatures are necessary. Key collisions occur with property signatures.
|
|
37
37
|
/* eslint-disable @typescript-eslint/method-signature-style */
|
|
38
38
|
setTokenizer (t: Tokenizer): void
|
|
39
|
-
ngrams (sequence: string | string[], n: number, startSymbol: string | undefined, endSymbol: string | undefined, stats: true): NGramsStats
|
|
40
|
-
ngrams (sequence: string | string[], n: number, startSymbol?: string, endSymbol?: string, stats?: boolean): string[][]
|
|
39
|
+
ngrams (sequence: string | string[], n: number, startSymbol: string | undefined | null, endSymbol: string | undefined | null, stats: true): NGramsStats
|
|
40
|
+
ngrams (sequence: string | string[], n: number, startSymbol?: string | undefined | null, endSymbol?: string, stats?: boolean): string[][]
|
|
41
41
|
bigrams (sequence: string | string[], startSymbol: string | undefined, endSymbol: string | undefined, stats: true): NGramsStats
|
|
42
42
|
bigrams (sequence: string | string[], startSymbol?: string, endSymbol?: string, stats?: boolean): string[][]
|
|
43
43
|
trigrams (sequence: string | string[], startSymbol: string | undefined, endSymbol: string | undefined, stats: true): NGramsStats
|
|
@@ -24,5 +24,28 @@ THE SOFTWARE.
|
|
|
24
24
|
|
|
25
25
|
export function normalize (tokens: string | string[]): string[]
|
|
26
26
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
27
|
-
export function
|
|
27
|
+
export function normalizeJa (str: string): string
|
|
28
|
+
export function normalizeNo (str: string): string
|
|
29
|
+
export function normalizeSv (str: string): string
|
|
28
30
|
export function removeDiacritics (str: string): string
|
|
31
|
+
|
|
32
|
+
export class Converters {
|
|
33
|
+
alphabetFH: (str: string) => string
|
|
34
|
+
alphabetHF: (str: string) => string
|
|
35
|
+
numbersFH: (str: string) => string
|
|
36
|
+
numbersHF: (str: string) => string
|
|
37
|
+
punctuationFH: (str: string) => string
|
|
38
|
+
punctuationHF: (str: string) => string
|
|
39
|
+
symbolFH: (str: string) => string
|
|
40
|
+
symbolHF: (str: string) => string
|
|
41
|
+
purePunctuationFH: (str: string) => string
|
|
42
|
+
purePunctuationHF: (str: string) => string
|
|
43
|
+
katakanaFH: (str: string) => string
|
|
44
|
+
katakanaHF: (str: string) => string
|
|
45
|
+
static fixFullwidthKana: (str: string) => string
|
|
46
|
+
static normalize: (str: string) => string
|
|
47
|
+
hiraganaToKatakana (str: string): string
|
|
48
|
+
katakanaToHiragana (str: string): string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type FixCompositeSymbolsTable = Record<string, string>
|
|
@@ -23,5 +23,8 @@ THE SOFTWARE.
|
|
|
23
23
|
'use strict'
|
|
24
24
|
|
|
25
25
|
exports.normalize = require('./normalizer').normalizeTokens
|
|
26
|
-
exports.
|
|
26
|
+
exports.normalizeJa = require('./normalizer_ja').normalizeJa
|
|
27
|
+
exports.normalizeNo = require('./normalizer_no').removeDiacritics
|
|
28
|
+
exports.normalizeSv = require('./normalizer_sv')
|
|
29
|
+
exports.Converters = require('./normalizer_ja').Converters
|
|
27
30
|
exports.removeDiacritics = require('./remove_diacritics')
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
const flip = require('../util/utils.js').flip
|
|
50
50
|
const merge = require('../util/utils.js').merge
|
|
51
|
-
const replacer = require('../util/utils').replacer
|
|
51
|
+
const replacer = require('../util/utils.js').replacer
|
|
52
52
|
|
|
53
53
|
// From http://fernweh.jp/b/mb_convert_kana_js/
|
|
54
54
|
const conversionTables = {
|
|
@@ -522,73 +522,110 @@ conversionTables.normalize = merge(
|
|
|
522
522
|
conversionTables.halfwidthToFullwidth.katakana
|
|
523
523
|
)
|
|
524
524
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
return
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
525
|
+
class Converters {
|
|
526
|
+
alphabetFH (str) {
|
|
527
|
+
return replacer(conversionTables.fullwidthToHalfwidth.alphabet)(str)
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
numbersFH (str) {
|
|
531
|
+
return replacer(conversionTables.fullwidthToHalfwidth.numbers)(str)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
symbolFH (str) {
|
|
535
|
+
return replacer(conversionTables.fullwidthToHalfwidth.symbol)(str)
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
purePunctuationFH (str) {
|
|
539
|
+
return replacer(conversionTables.fullwidthToHalfwidth.purePunctuation)(str)
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
punctuationFH (str) {
|
|
543
|
+
return replacer(conversionTables.fullwidthToHalfwidth.punctuation)(str)
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
katakanaFH (str) {
|
|
547
|
+
return replacer(conversionTables.fullwidthToHalfwidth.katakana)(str)
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
static fixFullwidthKana (str) {
|
|
551
|
+
return replacer(fixFullwidthKana)(str)
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
static normalize (str) {
|
|
555
|
+
return replacer(conversionTables.normalize)(str)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
alphabetHF (str) {
|
|
559
|
+
return replacer(conversionTables.halfwidthToFullwidth.alphabet)(str)
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
numbersHF (str) {
|
|
563
|
+
return replacer(conversionTables.halfwidthToFullwidth.numbers)(str)
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
symbolHF (str) {
|
|
567
|
+
return replacer(conversionTables.halfwidthToFullwidth.symbol)(str)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
purePunctuationHF (str) {
|
|
571
|
+
return replacer(conversionTables.halfwidthToFullwidth.purePunctuation)(str)
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
punctuationHF (str) {
|
|
575
|
+
return replacer(conversionTables.halfwidthToFullwidth.punctuation)(str)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
katakanaHF (str) {
|
|
579
|
+
return replacer(conversionTables.halfwidthToFullwidth.katakana)(str)
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
static fixCompositeSymbols (str) {
|
|
583
|
+
return replacer(fixCompositeSymbolsTable)(str)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Convert hiragana to fullwidth katakana.
|
|
588
|
+
* According to http://jsperf.com/converting-japanese, these implementations are
|
|
589
|
+
* faster than using lookup tables.
|
|
590
|
+
*
|
|
591
|
+
* @param {string} str A string.
|
|
592
|
+
* @return {string} A string not containing hiragana.
|
|
593
|
+
*/
|
|
594
|
+
hiraganaToKatakana (str) {
|
|
595
|
+
str = this.katakanaHF(str)
|
|
596
|
+
str = Converters.fixFullwidthKana(str)
|
|
597
|
+
|
|
598
|
+
str = str.replace(/ゝ/g, 'ヽ')
|
|
599
|
+
str = str.replace(/ゞ/g, 'ヾ')
|
|
600
|
+
// str = str.replace(/?/g, '𛀀'); // Letter archaic E
|
|
601
|
+
|
|
602
|
+
str = str.replace(/[ぁ-ゖ]/g, function (str) {
|
|
603
|
+
return String.fromCharCode(str.charCodeAt(0) + 96)
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
return str
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Convert katakana to hiragana.
|
|
611
|
+
*
|
|
612
|
+
* @param {string} str A string.
|
|
613
|
+
* @return {string} A string not containing katakana.
|
|
614
|
+
*/
|
|
615
|
+
katakanaToHiragana (str) {
|
|
616
|
+
str = this.katakanaHF(str)
|
|
617
|
+
str = Converters.fixFullwidthKana(str)
|
|
618
|
+
|
|
619
|
+
str = str.replace(/ヽ/g, 'ゝ')
|
|
620
|
+
str = str.replace(/ヾ/g, 'ゞ')
|
|
621
|
+
// str = str.replace(/?/g, '𛀁'); // Letter archaic E
|
|
622
|
+
|
|
623
|
+
str = str.replace(/[ァ-ヶ]/g, function (str) {
|
|
624
|
+
return String.fromCharCode(str.charCodeAt(0) - 96)
|
|
625
|
+
})
|
|
626
|
+
|
|
627
|
+
return str
|
|
628
|
+
}
|
|
592
629
|
}
|
|
593
630
|
|
|
594
631
|
/**
|
|
@@ -610,14 +647,14 @@ const normalizeJa = function (str) {
|
|
|
610
647
|
.replace(/(..)々々/g, '$1$1')
|
|
611
648
|
.replace(/(.)々/g, '$1$1')
|
|
612
649
|
|
|
613
|
-
str =
|
|
614
|
-
str =
|
|
650
|
+
str = Converters.normalize(str)
|
|
651
|
+
str = Converters.fixFullwidthKana(str)
|
|
615
652
|
|
|
616
653
|
// Replace composite symbols.
|
|
617
|
-
str = fixCompositeSymbols(str)
|
|
654
|
+
str = Converters.fixCompositeSymbols(str)
|
|
618
655
|
|
|
619
656
|
return str
|
|
620
657
|
}
|
|
621
658
|
|
|
622
659
|
exports.normalizeJa = normalizeJa
|
|
623
|
-
exports.
|
|
660
|
+
exports.Converters = Converters
|
|
@@ -22,6 +22,8 @@ THE SOFTWARE.
|
|
|
22
22
|
|
|
23
23
|
'use strict'
|
|
24
24
|
|
|
25
|
+
const Phonetic = require('./phonetic')
|
|
26
|
+
|
|
25
27
|
/*
|
|
26
28
|
* Daitch-Mokotoff Soundex Coding
|
|
27
29
|
*
|
|
@@ -195,69 +197,68 @@ const codes = {
|
|
|
195
197
|
}
|
|
196
198
|
/* jscpd:ignore-end */
|
|
197
199
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
class SoundExDM extends Phonetic {
|
|
201
|
+
process (word, codeLength) {
|
|
202
|
+
codeLength = codeLength || 6
|
|
203
|
+
word = word.toUpperCase()
|
|
204
|
+
let output = ''
|
|
205
|
+
|
|
206
|
+
let pos = 0; let lastCode = -1
|
|
207
|
+
while (pos < word.length) {
|
|
208
|
+
const substr = word.slice(pos)
|
|
209
|
+
const rules = this.findRules(substr)
|
|
202
210
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
let code
|
|
212
|
+
if (pos === 0) {
|
|
213
|
+
// at the beginning of the word
|
|
214
|
+
code = rules.mapping[0]
|
|
215
|
+
} else if (substr[rules.length] && this.findRules(substr[rules.length]).mapping[0] === 0) {
|
|
216
|
+
// before a vowel
|
|
217
|
+
code = rules.mapping[1]
|
|
218
|
+
} else {
|
|
219
|
+
// any other situation
|
|
220
|
+
code = rules.mapping[2]
|
|
221
|
+
}
|
|
207
222
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
code = rules.mapping[0]
|
|
212
|
-
} else if (substr[rules.length] && findRules(substr[rules.length]).mapping[0] === 0) {
|
|
213
|
-
// before a vowel
|
|
214
|
-
code = rules.mapping[1]
|
|
215
|
-
} else {
|
|
216
|
-
// any other situation
|
|
217
|
-
code = rules.mapping[2]
|
|
223
|
+
if ((code !== -1) && (code !== lastCode)) output += code
|
|
224
|
+
lastCode = code
|
|
225
|
+
pos += rules.length
|
|
218
226
|
}
|
|
219
227
|
|
|
220
|
-
|
|
221
|
-
lastCode = code
|
|
222
|
-
pos += rules.length
|
|
228
|
+
return this.normalizeLength(output, codeLength)
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
let state = codes[str[0]]
|
|
230
|
-
let legalState = state || [[-1, -1, -1]]
|
|
231
|
-
let charsInvolved = 1
|
|
231
|
+
findRules (str) {
|
|
232
|
+
let state = codes[str[0]]
|
|
233
|
+
let legalState = state || [[-1, -1, -1]]
|
|
234
|
+
let charsInvolved = 1
|
|
232
235
|
|
|
233
|
-
|
|
234
|
-
|
|
236
|
+
for (let offs = 1; offs < str.length; offs++) {
|
|
237
|
+
if (!state || !state[str[offs]]) break
|
|
235
238
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
239
|
+
state = state[str[offs]]
|
|
240
|
+
if (state[0]) {
|
|
241
|
+
legalState = state
|
|
242
|
+
charsInvolved = offs + 1
|
|
243
|
+
}
|
|
240
244
|
}
|
|
241
|
-
}
|
|
242
245
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
+
return {
|
|
247
|
+
length: charsInvolved,
|
|
248
|
+
mapping: legalState[0]
|
|
249
|
+
}
|
|
246
250
|
}
|
|
247
|
-
}
|
|
248
251
|
|
|
249
|
-
/**
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
/**
|
|
253
|
+
* Pad right with zeroes or cut excess symbols to fit length
|
|
254
|
+
*/
|
|
255
|
+
normalizeLength (token, length) {
|
|
256
|
+
length = length || 6
|
|
257
|
+
if (token.length < length) {
|
|
258
|
+
token += (new Array(length - token.length + 1)).join('0')
|
|
259
|
+
}
|
|
260
|
+
return token.slice(0, length)
|
|
256
261
|
}
|
|
257
|
-
return token.slice(0, length)
|
|
258
262
|
}
|
|
259
263
|
|
|
260
|
-
|
|
261
|
-
const soundex = new Phonetic()
|
|
262
|
-
soundex.process = process
|
|
263
|
-
module.exports = soundex
|
|
264
|
+
module.exports = SoundExDM
|