2016-09-26 15 views
2

ユニコードテキストを分割するためのテストケースがありますが、その方法はわかりません。ここでユニコードと句読点付きのJavascript regexp

describe("garden: utils",() => { 
    it("should split correctly",() => { 
    assert.deepEqual(segmentation('Hockey is a popular sport in Canada.'), [ 
     'Hockey', 'is', 'a', 'popular', 'sport', 'in', 'Canada', '.' 
    ]); 

    assert.deepEqual(segmentation('How many provinces are there in Canada?'), [ 
     'How', 'many', 'provinces', 'are', 'there', 'in', 'Canada', '?' 
    ]); 

    assert.deepEqual(segmentation('The forest is on fire!'), [ 
     'The', 'forest', 'is', 'on', 'fire', '!' 
    ]); 

    assert.deepEqual(segmentation('Emily Carr, who was born in 1871, was a great painter.'), [ 
     'Emily', 'Carr', ',', 'who', 'was', 'born', 'in', '1871', ',', 'was', 'a', 'great', 'painter', '.' 
    ]); 

    assert.deepEqual(segmentation('This is David\'s computer.'), [ 
     'This', 'is', 'David', '\'', 's', 'computer', '.' 
    ]); 

    assert.deepEqual(segmentation('The prime minister said, "We will win the election."'), [ 
     'The', 'prime', 'minister', 'said', ',', '"', 'We', 'will', 'win', 'the', 'election', '.', '"' 
    ]); 

    assert.deepEqual(segmentation('There are three positions in hockey: goalie, defence, and forward.'), [ 
     'There', 'are', 'three', 'positions', 'in', 'hockey', ':', 'goalie', ',', 'defence', ',', 'and', 'forward', '.' 
    ]); 

    assert.deepEqual(segmentation('The festival is very popular; people from all over the world visit each year.'), [ 
     'The', 'festival', 'is', 'very', 'popular', ';', 'people', 'from', 'all', 'over', 'the', 'world', 
     'visit', 'each', 'year', '.' 
    ]); 

    assert.deepEqual(segmentation('Mild, wet, and cloudy - these are the characteristics of weather in Vancouver.'), [ 
     'Mild', ',', 'wet', ',', 'and', 'cloudy', '-', 'these', 'are', 'the', 'characteristics', 'of', 'weather', 
     'in', 'Vancouver', '.' 
    ]); 

    assert.deepEqual(segmentation('sweet-smelling'), [ 
     'sweet', '-', 'smelling' 
    ]); 
    }); 

    it("should not split unicoded words",() => { 
    assert.deepEqual(segmentation('hacer a propósito'), [ 
     'hacer', 'a', 'propósito' 
    ]); 

    assert.deepEqual(segmentation('nhà em có con mèo'), [ 
     'nhà', 'em', 'có', 'con', 'mèo' 
    ]); 
    }); 

    it("should group periods",() => { 
    assert.deepEqual(segmentation('So are ... the fishes.'), [ 
     'So', 'are', '...', 'the', 'fishes', '.' 
    ]); 

    assert.deepEqual(segmentation('So are ...... the fishes.'), [ 
     'So', 'are', '......', 'the', 'fishes', '.' 
    ]); 

    assert.deepEqual(segmentation('arriba arriba ja....'), [ 
     'arriba', 'arriba', 'ja', '....' 
    ]); 
    }); 
}); 

Pythonで同等の式である:

class Segmentation(BaseNLPProcessor): 
    pattern = re.compile('((?u)\w+|\.{2,}|[%s])' % string.punctuation) 

    @classmethod 
    def ignore_value(cls, value): 
     # type: (str) -> bool 
     return negate(compose(is_empty, string.strip))(value) 

    def split(self): 
     # type:() -> List[str] 
     return filter(self.ignore_value, self.pattern.split(self.value())) 

私は、ユニコードに変換された単語や句読点によって複数のドットでグループを分割するjavascriptのためのPythonで同等の機能を書きたい...

Segmentation("Hockey is a popular sport in Canada.").split() 

答えて

3

JavaScript RegExpに負のルック・バック・アサーションはありません。Unicodeのサポートはまだ正式ではありません(現時点では、Firefoxでのみサポートされています)。これは、ライブラリ(XRegExp)を使用してUnicodeクラスを処理します。正規の完全正規表現が必要な場合はです。それは巨大ですです。ただコメントしてお知らせください。私は、Unicodeの範囲を含む分解された正規のRegExpステートメントを使用する答えを更新します。

const rxLetterToOther = XRegExp('(\\p{L})((?!\\s)\\P{L})','g'); 
const rxOtherToLetter = XRegExp('((?!\\s)\\P{L})(\\p{L})','g'); 
const rxNumberToOther = XRegExp('(\\p{N})((?!\\s)\\P{N})','g'); 
const rxOtherToNumber = XRegExp('((?!\\s)\\P{N})(\\p{N})','g'); 
const rxPuctToPunct = XRegExp('(\\p{P})(\\p{P})','g'); 
const rxSep = XRegExp('\\s+','g'); 

function segmentation(s) { 
    return s 
    .replace(rxLetterToOther, '$1 $2') 
    .replace(rxOtherToLetter, '$1 $2') 
    .replace(rxNumberToOther, '$1 $2') 
    .replace(rxOtherToNumber, '$1 $2') 
    .replace(rxPuctToPunct, '$1 $2') 
    .split(rxSep); 
} 

Here it is passing all the test cases!

window.onbeforeunload = "";
* { margin: 0; padding: 0; border: 0; overflow: hidden; } 
 
object { width: 100%; height: 100%; width: 100vw; height: 100vh; }
<object data="https://fiddle.jshell.net/a3tf68ae/14/show/" />

編集:テスト結果の下に巨大な正規表現のソースを印刷するには、テストケースを更新しました。スニペットを実行して、埋め込みテストケースを表示します。

+0

https://jsfiddle.net/hungphan/9u0javhg/ –

+0

@HungPhanそこに行く人のために別の単純な答えを持っています。それは厳しいものです。 – TylerY86

+0

ありがとう@ TylerY86。 –

1

私は答えを見つけましたが、それは複雑です。誰もがこの

module.exports = (string) => { 
    const segs = string.split(/(\.{2,}|!|"|#|$|%|&|'|\(|\)|\*|\+|,|-|\.|\/|:|;|<|=|>|\?|¿|@|[|]|\\|^|_|`|{|\||}|~|)/); 

    return segs.filter((seg) => seg.trim() !== ""); 
}; 
+0

構文にエラーがあります...正しく貼り付けられましたか? – TylerY86

+0

ここでテストケースに差し込まれます。 https://jsfiddle.net/9u0javhg/17/ – TylerY86

+0

参考までに、いくつか失敗しています... – TylerY86

関連する問題