TLDR
আপনি যদি দ্রুততম রেজেক্স-ভিত্তিক সমাধান চান তবে এই পদ্ধতিটি ব্যবহার করুন। ওপি'র মতো ডেটাসেটের জন্য, এটি গৃহীত উত্তরের চেয়ে প্রায় 1000 গুণ বেশি দ্রুত।
আপনি যদি রেজেক্সের বিষয়ে চিন্তা না করেন তবে এই সেট-ভিত্তিক সংস্করণটি ব্যবহার করুন যা একটি রেইজেক্স ইউনিয়নের চেয়ে 2000 গুণ দ্রুত is
ট্রির সাথে অপটিমাইজড রেজেক্স
অনেকগুলি নিষিদ্ধ শব্দের সাথে একটি সাধারণ রেজেক্স ইউনিয়ন পদ্ধতি ধীর হয়ে যায়, কারণ রেজেক্স ইঞ্জিন প্যাটার্নটি অনুকূলকরণের খুব ভাল কাজ করে না ।
নিষিদ্ধ সমস্ত শব্দ দিয়ে একটি ট্রি তৈরি করা এবং সংশ্লিষ্ট রেজেক্স লেখা সম্ভব। ফলস্বরূপ ট্রাই বা রেজেক্স প্রকৃতপক্ষে মানব-পঠনযোগ্য নয়, তবে তারা খুব দ্রুত অনুসন্ধান এবং মিলের জন্য অনুমতি দেয়।
উদাহরণ
['foobar', 'foobah', 'fooxar', 'foozap', 'fooza']
তালিকাটি একটি ট্রিতে রূপান্তরিত হয়েছে:
{
'f': {
'o': {
'o': {
'x': {
'a': {
'r': {
'': 1
}
}
},
'b': {
'a': {
'r': {
'': 1
},
'h': {
'': 1
}
}
},
'z': {
'a': {
'': 1,
'p': {
'': 1
}
}
}
}
}
}
}
এবং তারপরে এই রেজেক্স প্যাটার্নে:
r"\bfoo(?:ba[hr]|xar|zap?)\b"
বিশাল সুবিধাটি হ'ল zoo
ম্যাচগুলি পরীক্ষা করার জন্য , রেজেক্স ইঞ্জিনটি কেবলমাত্র 5 টি শব্দের চেষ্টা করার পরিবর্তে প্রথম অক্ষরটির সাথে (এটি মেলে না) তুলনা করা প্রয়োজন । এটি 5 টি শব্দের জন্য একটি প্রিপ্রসেস ওভারকিল, তবে এটি অনেক হাজার শব্দের জন্য আশাব্যঞ্জক ফলাফল দেখায়।
নোট (?:)
-ক্যাপচারিং গ্রুপগুলি ব্যবহার করা হয়েছে বলে নোট করুন :
কোড
এখানে সামান্য পরিবর্তিত এর সারকথা , যা আমরা হিসেবে ব্যবহার করতে পারেন trie.py
গ্রন্থাগার:
import re
class Trie():
"""Regex::Trie in Python. Creates a Trie out of a list of words. The trie can be exported to a Regex pattern.
The corresponding Regex should match much faster than a simple Regex union."""
def __init__(self):
self.data = {}
def add(self, word):
ref = self.data
for char in word:
ref[char] = char in ref and ref[char] or {}
ref = ref[char]
ref[''] = 1
def dump(self):
return self.data
def quote(self, char):
return re.escape(char)
def _pattern(self, pData):
data = pData
if "" in data and len(data.keys()) == 1:
return None
alt = []
cc = []
q = 0
for char in sorted(data.keys()):
if isinstance(data[char], dict):
try:
recurse = self._pattern(data[char])
alt.append(self.quote(char) + recurse)
except:
cc.append(self.quote(char))
else:
q = 1
cconly = not len(alt) > 0
if len(cc) > 0:
if len(cc) == 1:
alt.append(cc[0])
else:
alt.append('[' + ''.join(cc) + ']')
if len(alt) == 1:
result = alt[0]
else:
result = "(?:" + "|".join(alt) + ")"
if q:
if cconly:
result += "?"
else:
result = "(?:%s)?" % result
return result
def pattern(self):
return self._pattern(self.dump())
পরীক্ষা
এখানে একটি ছোট পরীক্ষা (হিসাবে একই এই এক ):
# Encoding: utf-8
import re
import timeit
import random
from trie import Trie
with open('/usr/share/dict/american-english') as wordbook:
banned_words = [word.strip().lower() for word in wordbook]
random.shuffle(banned_words)
test_words = [
("Surely not a word", "#surely_NöTäWORD_so_regex_engine_can_return_fast"),
("First word", banned_words[0]),
("Last word", banned_words[-1]),
("Almost a word", "couldbeaword")
]
def trie_regex_from_words(words):
trie = Trie()
for word in words:
trie.add(word)
return re.compile(r"\b" + trie.pattern() + r"\b", re.IGNORECASE)
def find(word):
def fun():
return union.match(word)
return fun
for exp in range(1, 6):
print("\nTrieRegex of %d words" % 10**exp)
union = trie_regex_from_words(banned_words[:10**exp])
for description, test_word in test_words:
time = timeit.timeit(find(test_word), number=1000) * 1000
print(" %s : %.1fms" % (description, time))
এটি ফলাফল:
TrieRegex of 10 words
Surely not a word : 0.3ms
First word : 0.4ms
Last word : 0.5ms
Almost a word : 0.5ms
TrieRegex of 100 words
Surely not a word : 0.3ms
First word : 0.5ms
Last word : 0.9ms
Almost a word : 0.6ms
TrieRegex of 1000 words
Surely not a word : 0.3ms
First word : 0.7ms
Last word : 0.9ms
Almost a word : 1.1ms
TrieRegex of 10000 words
Surely not a word : 0.1ms
First word : 1.0ms
Last word : 1.2ms
Almost a word : 1.2ms
TrieRegex of 100000 words
Surely not a word : 0.3ms
First word : 1.2ms
Last word : 0.9ms
Almost a word : 1.6ms
তথ্যের জন্য, রেজেক্স শুরু হয়:
(: একটি (: (: \ 'র | A (: \'?? গুলি | চেন | liyah (: \ 'গুলি) | আর (:? Dvark (: (: \' র | গুলি )) | দিকে)) | খ? (: \ 'র | A (: C (: আমাদের (: (: \??' গুলি | স্প্যানিশ ভাষায়)) | [Ik]) | ফুট | নির্জন (? : (: \ 'র | গুলি)?) | ndon (? :( ?: ইডি | ing | ment (: \' গুলি) |?? গুলি)) | গুলি (: ই (:( ?:? ment: | [DS])) | জ (:( ?: ই [DS] | ing)) | ing) | T ((\ 'র?):??? ই (:( ?: ment ( : \ 'গুলি) | [DS])) | ing | toir (: (: \?' র | গুলি)))) | বি (: হিসাবে (:? ID) | ই (? : SS (: (: \ 'র | স্প্যানিশ ভাষায়)) |? ওয়াই (: (: \?' |) | OT (গুলি গুলি)):? (?? \ 'এর | T (: \ 'গুলি) | গুলি)) | reviat? (: ই [DS] | আমি (:? ng | উপর (: (: \?' র | গুলি)))) | ওয়াই (:? \ ' ? গুলি) | \ e (: (: \ 'র | গুলি)?)) | ঘ (: icat (: ই [DS] | আমি (?? ng | উপর (:? (: \ এর | গুলি)))) | ওম (: স্বীকারোক্তি (: (: \?? 'গুলি | গুলি)) | সারাই) | তোমার দর্শন লগ করা (?? CT (:( ?: ইডি | আমি (?: NG | উপর (: (: \? 'র | গুলি))) | অথবা (: (: \' র | গুলি)??) | গুলি)) | ঠ (: \ 'র)) ) | ই (: (: \ 'র | টার | ঠ (: (: \' র | Ard | পুত্র (?? \ 'গুলি))) | আর (:? দীন (: \ 'গুলি) | nathy? (: \' গুলি) | রা (:? NT | হত্যার (: (: \ 'র | গুলি))??)) | T (:( ?: T (?: ই (: আর (: (: \? 'র | গুলি)) | ঘ?) | ing | অথবা (: (: \'গুলি | গুলি))) | গুলি)) | yance (:? \ 'গুলি) | ঘ)) | Hor (:( ?: আর (:?? ই (: N (: সিই (?? : \ 'গুলি) | T) | ঘ) | ing) | গুলি)) | আমি (?? ঘ (: ই [DS] | ing | জানুয়ারী (:? \'? গুলি)) | Gail | ঠ (: ene থেকে | এটা (:? ies এর | ওয়াই (: \ 'র))?) | ঞ | উর ((: ect, (Ly?):?? ation (: (: \?)' গুলি | গুলি)) | ই [DS] | ing)) | ঠ (:?? A (: tive (: (:? \ 'র | গুলি)) | Ze) | ই (:(? : ST | R)) | হলে OOM kills | ution (: (:? \ '? গুলি | গুলি)) | Y) | মি \' এর | এন (: ই (: খাল (: ই [DS] ? | আমি (: nG | উপর (: \ 'গুলি)?) | R (?: \?)' র)) | ormal (:( ?: এটা (:? ies এর | ওয়াই (:? \ ' গুলি)) | Ly))) | O (:? Ard | ডি (: (:? \ 'র | গুলি)) | লি (: SH (:( ?: ই [DS] | ING )) | হত্যার? (: (: \ 'র | আইএসটি (: (: \?' র | গুলি))))) | Mina (:? BL [ey] | T (: ই [ DS] | আমি? (: nG | উপর (:? (: \ 'র | গুলি))?))) | আর (:?? igin (: আল (: (: \' র | গুলি) ) | ই? (: (: \ 'র | গুলি))) | T (:( ?: ইডি | আমি (:? ng | উপর (: (: \' র | আইএসটি (?: ) |)) s | ve) | গুলি))) | তোমার দর্শন লগ করা (|: (\ 'এস এস?):??? য় (:( ?: ইডি | ing | গুলি)) | T) | ve (: (: \ 'র | বোর্ড))) | আর (:? A (: cadabra (: \?' গুলি) | ঘ (:? ই [DS] | ing) | হ্যাম (? : \ '? গুলি) | মিটার (: (: \' র | গুলি)?) | Si (: চালু (: (:? \ 'এর | গুলি)) |? ve (:( ?:?\ 'এর | ly থেকে | Ness (: \?' | গুলি)))) | পূর্ব | idg (গুলি):? ই (:( ?: ment (: (:? \ 'এর | গুলি)) ? | [DS])) | ing | ment (:? (: \ 'র | গুলি))) | O (:? বিজ্ঞাপন | খাল (: ই [DS] | আমি (?? ng | উপর (: (: \?? 'র | গুলি))))) | upt (:( ?: ই (:?? St | R) | ly থেকে | Ness (: \' র)))) | গুলি (:? আলম | C (: কানা অনুলিপি করুন (: (: \ 'র | ই [DS] | ing)) | ইসা (: (: \'?? গুলি | [স্প্যানিশ ভাষায়])) | ond)) | স্বীকারোক্তি (:( ?: ইডি | | ing গুলি?)? (: সিই (: (: \ 'র | গুলি)??) | T (:( ?: ই (: ই ( ?: (: \ 'র | আইএসএস (: \?' গুলি) | গুলি?)) | ঘ) | ing | ly থেকে | গুলি))) | inth (: (: \ 'র | ই ( : \ 'গুলি))) | ণ? (?? ঠ (: uT (: ই (: (: \?' র | ly থেকে | St)?) | আমি (:? উপর (?: \ '? গুলি) | ছাঃ (: \'? গুলি))) | V (: ই [DS] | ing)) | আর (:? বি (:( ?: ই (: N (?? : CY (: \? '| টন গুলি)? (: (: \' র | গুলি))??) | ঘ) | ing | গুলি)) | পিটিআই ...গুলি | [স্প্যানিশ ভাষায়])) | ond (:( ?: ইডি | ing | গুলি))) | স্বীকারোক্তি (:?? সিই (: (:? \ 'এর | গুলি)) | T (?: (: ই (: ই (: (:? \ '? গুলি | আইএসএস (: \'? গুলি) | গুলি)) | ঘ) | ing | ly থেকে | গুলি))) | inth (?: (: \ 'র | ই (: \?' গুলি)?)) | O (:? ঠ (: uT (: ই (: (: \ 'র | ly থেকে | St))??? | আমি (: চালু (: \ 'গুলি) | ছাঃ (: \'?? গুলি))?) | V (: ই [DS] | ing)) | আর (:? বি (:( : ই (: N (: CY (: \ 'গুলি) | T (: (:? \'?? গুলি | গুলি))) | ঘ) |? ing | গুলি)) | পিটিআই .. ।গুলি | [স্প্যানিশ ভাষায়])) | ond (:( ?: ইডি | ing | গুলি))) | স্বীকারোক্তি (:?? সিই (: (:? \ 'এর | গুলি)) | T (?: (: ই (: ই (: (:? \ '? গুলি | আইএসএস (: \'? গুলি) | গুলি)) | ঘ) | ing | ly থেকে | গুলি))) | inth (?: (: \ 'র | ই (: \?' গুলি)?)) | O (:? ঠ (: uT (: ই (: (: \ 'র | ly থেকে | St))??? | আমি (: চালু (: \ 'গুলি) | ছাঃ (: \'?? গুলি))?) | V (: ই [DS] | ing)) | আর (:? বি (:( : ই (: N (: CY (: \ 'গুলি) | T (: (:? \'?? গুলি | গুলি))) | ঘ) |? ing | গুলি)) | পিটিআই .. ।
এটি সত্যিই অপঠনযোগ্য, তবে 100000 নিষিদ্ধ শব্দের তালিকার জন্য, এই ট্রি রেজেক্স একটি সাধারণ রেইজেক্স ইউনিয়নের চেয়ে 1000 গুণ বেশি দ্রুত!
ট্রাই-পাইথন-গ্রাফভিজ এবং গ্রাফভিজের সাথে রফতানি করা সম্পূর্ণ ট্রাইয়ের চিত্র এখানে রয়েছে twopi
: