2016-09-26 3 views
2

유니 코드 된 단어를 분리하기위한 테스트 사례가 있지만 자바 스크립트에서 수행하는 방법을 알지 못합니다. 여기 유니 코드와 구두점이있는 자바 스크립트 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', '....' 
    ]); 
    }); 
}); 

는 파이썬에 해당하는 식입니다

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())) 

내가 여러 점으로 유니 코드의 단어와 문장 부호 그룹으로 분할하는 자바 스크립트를 파이썬에 해당하는 함수를 작성하려면 ...

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

답변

3

자바 스크립트 RegExp에는 부정적인 뒤집기 어설 션이 없으며 유니 코드 지원은 공식적으로 아직 공식적으로 지원되지 않습니다 (현재 Firefox에서 플래그로만 지원됨). 라이브러리 (XRegExp)를 사용하여 유니 코드 클래스를 처리합니다. 완전한 일반 정규 표현식이 필요하면 이 대단합니다.입니다. 그냥 의견을 말하자면, 유니 코드 범위를 포함하는 분해 된 일반 RegExp 문을 사용하도록 해답을 업데이트 할 것입니다.

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/" />

Here it is passing all the test cases!

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); 
} 

편집 : 테스트 결과 아래에 거대한 정규식 소스를 인쇄 할 수있는 테스트 케이스를 업데이트했습니다. 스 니펫을 실행하여 내장 테스트 케이스를 확인하십시오.

+0

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

+0

@HungPhan이 당신이가는 사람을 위해 또 다른 간단한 대답이 있습니까. 그것은 힘든 일입니다. – TylerY86

+0

Thanks @ 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