alv*_*vas 5 python regex string nlp n-gram
以下word2ngrams函数从一个单词中提取字符3gram:
>>> x = 'foobar'
>>> n = 3
>>> [x[i:i+n] for i in range(len(x)-n+1)]
['foo', 'oob', 'oba', 'bar']
Run Code Online (Sandbox Code Playgroud)
这篇文章显示了单个单词的字符ngram提取,使用python快速实现字符n-gram。
但是,如果我有句子并且想提取字符ngram,该word2ngram()怎么办呢?
实现相同word2ngram和sent2ngram输出的正则表达式版本是什么?会更快吗?
我试过了:
import string, random, time
from itertools import chain
def word2ngrams(text, n=3):
""" Convert word into character ngrams. """
return [text[i:i+n] for i in range(len(text)-n+1)]
def sent2ngrams(text, n=3):
return list(chain(*[word2ngrams(i,n) for i in text.lower().split()]))
def sent2ngrams_simple(text, n=3):
text = text.lower()
return [text[i:i+n] for i in range(len(text)-n+1) if not " " in text[i:i+n]]
# Generate 10000 random strings of length 100.
sents = [" ".join([''.join(random.choice(string.ascii_uppercase) for j in range(10)) for i in range(100)]) for k in range(100)]
start = time.time()
x = [sent2ngrams(i) for i in sents]
print time.time() - start
start = time.time()
y = [sent2ngrams_simple(i) for i in sents]
print time.time() - start
print x==y
Run Code Online (Sandbox Code Playgroud)
[出]:
0.0205280780792
0.0271739959717
True
Run Code Online (Sandbox Code Playgroud)
已编辑
regex方法看起来很优雅,但比迭代调用的执行速度慢word2ngram():
import string, random, time, re
from itertools import chain
def word2ngrams(text, n=3):
""" Convert word into character ngrams. """
return [text[i:i+n] for i in range(len(text)-n+1)]
def sent2ngrams(text, n=3):
return list(chain(*[word2ngrams(i,n) for i in text.lower().split()]))
def sent2ngrams_simple(text, n=3):
text = text.lower()
return [text[i:i+n] for i in range(len(text)-n+1) if not " " in text[i:i+n]]
def sent2ngrams_regex(text, n=3):
rgx = '(?=('+'\S'*n+'))'
return re.findall(rgx,text)
# Generate 10000 random strings of length 100.
sents = [" ".join([''.join(random.choice(string.ascii_uppercase) for j in range(10)) for i in range(100)]) for k in range(100)]
start = time.time()
x = [sent2ngrams(i) for i in sents]
print time.time() - start
start = time.time()
y = [sent2ngrams_simple(i) for i in sents]
print time.time() - start
start = time.time()
z = [sent2ngrams_regex(i) for i in sents]
print time.time() - start
print x==y==z
Run Code Online (Sandbox Code Playgroud)
[出]:
0.0211708545685
0.0284190177917
0.0303599834442
True
Run Code Online (Sandbox Code Playgroud)
小智 6
为什么不只是(?=(...))
edit 相同的内容,但不是空格(?=(\S\S\S))
edit2您也可以使用您想要的内容。前任。仅使用字母(?=([^\W_]{3}))
使用前瞻捕获 3 个字符。然后引擎在每场比赛中将排名提升 1 次
。然后捕获下 3 个。
结果foobar是
foo
oob
oba
bar
# Compressed regex
# (?=(...))
# Expanded regex
(?= # Start Lookahead assertion
( # Capture group 1 start
. # dot - metachar, matches any character except newline
. # dot - metachar
. # dot - metachar
) # Capture group 1 end
) # End Lookahead assertion
Run Code Online (Sandbox Code Playgroud)