পাইথন 3-এ কয়েক মিলিয়ন রেজেস প্রতিস্থাপনের গতি বাড়িয়েছে


127

আমি পাইথন 3.5.5 ব্যবহার করছি

আমার দুটি তালিকা আছে

  • প্রায় 750,000 "বাক্য" (দীর্ঘ স্ট্রিং) এর একটি তালিকা
  • আমি আমার 750,000 বাক্যগুলি থেকে মুছে ফেলতে চাই এমন প্রায় 20,000 "শব্দ" এর একটি তালিকা

সুতরাং, আমি 750,000 বাক্যগুলির মধ্য দিয়ে লুপ করতে এবং প্রায় 20,000 প্রতিস্থাপন করতে হবে, তবে কেবলমাত্র যদি আমার শব্দগুলি "শব্দ" হয় এবং অক্ষরের বৃহত্তর স্ট্রিংয়ের অংশ না হয়।

আমি আমার কথাগুলি প্রাক-সংকলন করে এটি করছি যাতে সেগুলি \bমেটাচ্যারাক্টরের দ্বারা ফ্ল্যাঙ্ক করা হয়

compiled_words = [re.compile(r'\b' + word + r'\b') for word in my20000words]

তারপরে আমি আমার "বাক্যগুলি" দিয়ে লুপ করব

import re

for sentence in sentences:
  for word in compiled_words:
    sentence = re.sub(word, "", sentence)
  # put sentence into a growing list

এই নেস্টেড লুপটি প্রতি সেকেন্ডে প্রায় 50 টি বাক্য প্রক্রিয়াজাত করছে , যা দুর্দান্ত, তবে আমার সমস্ত বাক্য প্রক্রিয়া করতে এখনও কয়েক ঘন্টা সময় নেয়।

  • str.replaceপদ্ধতিটি ব্যবহার করার কি কোনও উপায় আছে (যা আমি বিশ্বাস করি যে দ্রুত) তবে প্রতিস্থাপনটি কেবলমাত্র শব্দের সীমানায় ঘটে ?

  • বিকল্পভাবে, re.subপদ্ধতিটি দ্রুত করার কোনও উপায় আছে কি? re.subআমার শব্দের দৈর্ঘ্য> আমার বাক্যটির দৈর্ঘ্যের চেয়ে কম থাকলে আমি ইতিমধ্যে গতিতে সামান্য পরিমাণে উন্নতি করেছি, তবে এটি কোনও উন্নতি নয় not

কোন পরামর্শ করার জন্য আপনাকে ধন্যবাদ।


1
এখানে প্রথম উত্তরে কিছু ভাল নমুনা কোড রয়েছে: স্ট্যাকওভারফ্লো / প্রশ্ন / 2846653/ … আপনি তারপরে এমন অনেকগুলি থ্রেড
মোহাম্মদ আলী

4
আপনি একটি নন-রেজেক্স বাস্তবায়নও চেষ্টা করতে পারেন - শব্দ দ্বারা আপনার ইনপুট শব্দটি অতিক্রম করুন এবং একটি সেট দিয়ে প্রতিটির সাথে মেলে। এটি একক পাস এবং হ্যাশ লুকআপ বেশ দ্রুত।
পিভিজি

2
ঘটনাচক্রে এই বাক্যগুলি কত দিন? 750 কে লাইনগুলি কোনও ডেটাসেটের মতো শোনাচ্ছে না যা প্রক্রিয়া করতে কয়েক ঘন্টা সময় নেওয়া উচিত।
পিভিজি

2
@ মোহাম্মদআলি: সিপিইউ-ভিত্তিক কাজের জন্য সেই উদাহরণ দিয়ে বিরক্ত করবেন না। পাইথনের একটি বড় লক রয়েছে যা বাইটোকোড (গ্লোবাল ইন্টারপ্রেটার লক) চালানোর সময় লাগে, সুতরাং আপনি সিপিইউ কাজের জন্য থ্রেড থেকে সুবিধা নিতে পারবেন না। আপনাকে multiprocessing(যেমন একাধিক পাইথন প্রক্রিয়া) ব্যবহার করতে হবে ।
কেভিন

1
এটি করার জন্য আপনার একটি শিল্প শক্তির সরঞ্জাম প্রয়োজন । স্ট্রিংগুলির তালিকার একটি ত্রয়ী গাছ থেকে একটি রেজেক্স ট্রাই উত্পন্ন হয়। এই ধরণের ম্যাচটি করার দ্রুততম পদ্ধতিতে ব্যর্থতার পক্ষে 5 টিরও বেশি ধাপ কখনও নেই। উদাহরণস্বরূপ: 175,000 শব্দের অভিধান বা আপনার নিষিদ্ধ তালিকার মতোই কেবল 20,000 এস-শব্দ
x15

উত্তর:


123

একটি জিনিস আপনি চেষ্টা করতে পারেন তা হল একটি একক প্যাটার্নের মতো সংকলন করা "\b(word1|word2|word3)\b"

reআসল ম্যাচিং করতে সি কোডের উপর নির্ভর করার কারণে, সঞ্চয়টি নাটকীয় হতে পারে।

@Pvg মন্তব্যগুলিতে যেমন উল্লেখ করেছে, এটি একক পাসের মিল থেকেও উপকৃত হয়।

যদি আপনার শব্দগুলি রেজেক্স না হয় তবে এরিকের উত্তর দ্রুত।


4
এটি কেবল সি ইম্পল নয় (যা একটি বড় পার্থক্য করে) তবে আপনি একক পাসের সাথেও মিল করছেন। এই প্রশ্নের রূপগুলি প্রায়শই প্রায়শই আসে, এটি বেশ অদ্ভুত কিছু নেই (বা সম্ভবত সেখানেও লুকিয়ে আছে?) এই চমত্কার বুদ্ধিমান ধারণাটির জন্য এটির জন্য একটি প্রমানিক এসও উত্তর।
পিভিজি

40
@ লাইটে আপনার পরামর্শটি 4 ঘন্টার কাজটিকে 4 মিনিটের কাজের মধ্যে পরিণত করেছে! আমি সমস্ত 20,000+ রিজিক্সগুলিকে একক বৃহতাত্ত্বিক রেজেক্সে যোগ দিতে সক্ষম হয়েছি এবং আমার ল্যাপটপ একটি চোখও ব্যাট করে না। আবার ধন্যবাদ.
পিডানিজ

2
@Bakuriu: s/They actually use/They actually could in theory sometimes use/। পাইথনের বাস্তবায়ন এখানে লুপ ব্যতীত অন্য কিছু করছে বলে বিশ্বাস করার কোনও যুক্তি আছে কি?
ব্যবহারকারী541686

2
@ বাকুরিউ: আমি যদি সত্যিই আগ্রহী তবে তা জানতে আগ্রহী, তবে আমি মনে করি না রেজেক্স সমাধানটি লিনিয়ার সময় নেয় takes যদি এটি ইউনিয়নের বাইরে কোনও ট্রেই তৈরি না করে, আমি কীভাবে এটি ঘটতে পারে তা দেখছি না।
এরিক ডুমিনিল

2
@ বাকুরিউ: এটি কোনও কারণ নয়। যদি আপনি বাস্তবায়ন বিশ্বাস করতে কোনো কারণ না থাকলে আমি জিজ্ঞাসা ছিল আসলে যে ভাবে আচরণ করবে কিনা না আপনি কি এটা বিশ্বাস করার জন্য একটি কারণ আছে পারে যে ভাবে আচরণ। ব্যক্তিগতভাবে আমি এখনও একটি একক মূলধারার প্রোগ্রামিং ল্যাঙ্গুয়েজের রেজেক্স বাস্তবায়ন দেখতে পেলাম যা আপনি যেমন ক্লাসিকাল রেজেক্সের প্রত্যাশা করতেন একইভাবে রৈখিক সময়ে কাজ করে, তাই যদি আপনি জানেন যে পাইথন এটি করেন, আপনার কিছু প্রমাণ দেখাতে হবে।
ব্যবহারকারী541686

123

TLDR

যদি আপনি দ্রুততম সমাধান চান তবে এই পদ্ধতিটি (সেট লক সহ) ব্যবহার করুন। ওপি'র মতো ডেটাসেটের জন্য, এটি গৃহীত উত্তরের চেয়ে প্রায় 2000 গুণ বেশি দ্রুত।

আপনি যদি অনুসন্ধানের জন্য একটি রেজেক্স ব্যবহার করার জন্য জোর দিয়ে থাকেন তবে এই ট্রাই-ভিত্তিক সংস্করণটি ব্যবহার করুন , যা এখনও রেগেক্স ইউনিয়নের চেয়ে 1000 গুণ বেশি গতিযুক্ত।

তত্ত্ব

যদি আপনার বাক্যগুলি হ্রাসযুক্ত স্ট্রিং না হয় তবে সম্ভবত প্রতি সেকেন্ডে 50 এরও বেশি প্রক্রিয়া করা সম্ভব।

যদি আপনি নিষিদ্ধ সমস্ত শব্দ একটি সেটে সংরক্ষণ করেন তবে সেই সেটটিতে আর একটি শব্দ অন্তর্ভুক্ত রয়েছে কিনা তা খতিয়ে দেখা খুব দ্রুত হবে।

যুক্তিটি কোনও কার্যক্রমে প্যাক করুন, যুক্তি হিসাবে এই ফাংশনটি দিন re.subএবং আপনি শেষ করেছেন!

কোড

import re
with open('/usr/share/dict/american-english') as wordbook:
    banned_words = set(word.strip().lower() for word in wordbook)


def delete_banned_words(matchobj):
    word = matchobj.group(0)
    if word.lower() in banned_words:
        return ""
    else:
        return word

sentences = ["I'm eric. Welcome here!", "Another boring sentence.",
             "GiraffeElephantBoat", "sfgsdg sdwerha aswertwe"] * 250000

word_pattern = re.compile('\w+')

for sentence in sentences:
    sentence = word_pattern.sub(delete_banned_words, sentence)

রূপান্তরিত বাক্যগুলি হ'ল:

' .  !
  .
GiraffeElephantBoat
sfgsdg sdwerha aswertwe

মনে রাখবেন যে:

  • অনুসন্ধান কেস-সংবেদনশীল (ধন্যবাদ lower())
  • একটি শব্দ প্রতিস্থাপন ""দুটি স্পেস ছেড়ে যেতে পারে (আপনার কোড হিসাবে)
  • পাইথন 3 এর সাথে উচ্চারণযুক্ত \w+অক্ষরগুলির সাথেও মিল রয়েছে (উদাঃ "ångström")।
  • যেকোন শব্দের অক্ষর (ট্যাব, স্পেস, নিউলাইন, চিহ্ন, ...) অচ্ছুত থাকবে।

কর্মক্ষমতা

মিলিয়ন বাক্য রয়েছে, banned_wordsপ্রায় 100000 শব্দ রয়েছে এবং স্ক্রিপ্টটি 7 এরও কম সময়ে চলে runs

তুলনায়, লাইটের উত্তরের জন্য 10 হাজার বাক্যটির জন্য 160s প্রয়োজন।

সঙ্গে nশব্দের মোট amound এবং হচ্ছে mনিষিদ্ধ শব্দ পরিমাণ, অপ এবং Liteye এর কোড হয় O(n*m)

তুলনায়, আমার কোডটি চালানো উচিত O(n+m)। নিষিদ্ধ শব্দের চেয়ে আরও অনেক বাক্য রয়েছে তা বিবেচনা করেই অ্যালগরিদম হয়ে যায় O(n)

রেজেক্স ইউনিয়ন পরীক্ষা

একটি '\b(word1|word2|...|wordN)\b'প্যাটার্ন দিয়ে একটি রেজেক্স অনুসন্ধানের জটিলতা কী ? এটা O(N)নাকি O(1)?

রেজেক্স ইঞ্জিন যেভাবে কাজ করে তা উপলব্ধি করা বেশ কঠিন, সুতরাং আসুন একটি সাধারণ পরীক্ষা লিখি।

এই কোডটি 10**iএলোমেলোভাবে ইংরেজী শব্দগুলিকে একটি তালিকায় বের করে। এটি সম্পর্কিত রেজেক্স ইউনিয়ন তৈরি করে এবং বিভিন্ন শব্দ দিয়ে এটি পরীক্ষা করে:

  • একটি পরিষ্কারভাবে একটি শব্দ নয় (এটি দিয়ে শুরু হয় #)
  • তালিকার প্রথম শব্দ word
  • একটি তালিকার শেষ শব্দ
  • একটি শব্দ মত চেহারা কিন্তু না


import re
import timeit
import random

with open('/usr/share/dict/american-english') as wordbook:
    english_words = [word.strip().lower() for word in wordbook]
    random.shuffle(english_words)

print("First 10 words :")
print(english_words[:10])

test_words = [
    ("Surely not a word", "#surely_NöTäWORD_so_regex_engine_can_return_fast"),
    ("First word", english_words[0]),
    ("Last word", english_words[-1]),
    ("Almost a word", "couldbeaword")
]


def find(word):
    def fun():
        return union.match(word)
    return fun

for exp in range(1, 6):
    print("\nUnion of %d words" % 10**exp)
    union = re.compile(r"\b(%s)\b" % '|'.join(english_words[:10**exp]))
    for description, test_word in test_words:
        time = timeit.timeit(find(test_word), number=1000) * 1000
        print("  %-17s : %.1fms" % (description, time))

এটি ফলাফল:

First 10 words :
["geritol's", "sunstroke's", 'fib', 'fergus', 'charms', 'canning', 'supervisor', 'fallaciously', "heritage's", 'pastime']

Union of 10 words
  Surely not a word : 0.7ms
  First word        : 0.8ms
  Last word         : 0.7ms
  Almost a word     : 0.7ms

Union of 100 words
  Surely not a word : 0.7ms
  First word        : 1.1ms
  Last word         : 1.2ms
  Almost a word     : 1.2ms

Union of 1000 words
  Surely not a word : 0.7ms
  First word        : 0.8ms
  Last word         : 9.6ms
  Almost a word     : 10.1ms

Union of 10000 words
  Surely not a word : 1.4ms
  First word        : 1.8ms
  Last word         : 96.3ms
  Almost a word     : 116.6ms

Union of 100000 words
  Surely not a word : 0.7ms
  First word        : 0.8ms
  Last word         : 1227.1ms
  Almost a word     : 1404.1ms

সুতরাং দেখে মনে হচ্ছে যে কোনও '\b(word1|word2|...|wordN)\b'প্যাটার্ন সহ একটি শব্দের অনুসন্ধান রয়েছে:

  • O(1) সর্বোত্তম ঘটনা
  • O(n/2) গড় কেস, যা এখনও আছে O(n)
  • O(n) সবচেয়ে খারাপ ক্ষেত্রে

এই ফলাফলগুলি একটি সাধারণ লুপ অনুসন্ধানের সাথে সামঞ্জস্যপূর্ণ।

একটি রেইগেক্স ইউনিয়নের অনেক দ্রুত বিকল্প হ'ল ট্রাই থেকে রেজেক্স প্যাটার্ন তৈরি করা ।


1
আপনি সঠিক ছিলেন। আমার ইনডেন্টেশন ভুল ছিল। আমি এটি মূল প্রশ্নে স্থির করেছি। 50 টি বাক্য / সেকেন্ড ধীর গতির মন্তব্যটির জন্য আমি যা বলতে পারি তা হ'ল আমি একটি সরলিকৃত উদাহরণ সরবরাহ করছি। আসল ডেটা-সেটটি আমি বর্ণনা করার চেয়ে জটিল, তবে এটি প্রাসঙ্গিক বলে মনে হয়নি। এছাড়াও, আমার "শব্দগুলি" একটি একক রেজেক্সে পরিণত করা গতির ব্যাপক উন্নতি করেছে। এছাড়াও, প্রতিস্থাপনের পরে আমি ডাবল স্পেসগুলি "আটকিয়ে" ফেলছি।
পিডানিজ

1
@ user36476 মতামতের জন্য ধন্যবাদ, আমি সংশ্লিষ্ট অংশটি সরিয়েছি। আপনি কি আমার পরামর্শ চেষ্টা করতে পারেন? আমি সাহস করে বলতে পারি এটি গৃহীত উত্তরের চেয়ে অনেক দ্রুত।
এরিক ডুমিনিল

1
যেহেতু আপনি সেই বিভ্রান্তিমূলক O(1)দাবিটি সরিয়েছেন , আপনার উত্তর অবশ্যই একটি আপ ভোটের দাবিদার।
ইডমিয়ান

1
@ আইডমিয়ান: সত্য, এটি খুব পরিষ্কার ছিল না। এটি সন্ধানের কথা উল্লেখ করছিল: "এই শব্দটি কি নিষিদ্ধ শব্দ?"
এরিক ডুমিনিল

1
@ এরিকডুমিনিল: দুর্দান্ত কাজ! আশা করি আমি দ্বিতীয়বারের মতো উঁচুতে পারতাম।
ম্যাথিউ এম।

105

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:

এখানে চিত্র বিবরণ লিখুন


দেখে মনে হচ্ছে যে আসল উদ্দেশ্যে, কোনও নন ক্যাপচারিং গোষ্ঠীর প্রয়োজন নেই। কমপক্ষে ক্যাপচারকারী গোষ্ঠীর অর্থ উল্লেখ করা উচিত
জ্যাভিয়ার

3
@ জাভিয়ারকোবেলে: আপনি ঠিক বলেছেন যে ক্যাপচারিং গ্রুপটির উল্লেখ করা উচিত: উত্তরটি আপডেট করা হয়েছে। যদিও আমি এটি অন্যদিকে দেখতে পাচ্ছি: সাথে রেইগেক্স পরিবর্তনের জন্য প্যারেনগুলি প্রয়োজন |তবে ক্যাপচারিং গ্রুপগুলি আমাদের উদ্দেশ্যটির জন্য মোটেই প্রয়োজন হয় না। তারা কেবল প্রক্রিয়াটি ধীর করবে এবং কোনও সুবিধা ছাড়াই আরও মেমরি ব্যবহার করবে।
এরিক ডুমিনিল

3
@ এরিকডুমিনিল এই পোস্টটি নিখুঁত, আপনাকে অনেক ধন্যবাদ :)
মোহাম্মদ আল এএনআই

1
@ মোহাম্মদলানি: কোন সমাধানের সাথে তুলনা করছেন?
এরিক ডুমিনিল

1
@ পিভি 8: এটি কেবল সম্পূর্ণ শব্দের সাথে মিলবে, হ্যাঁ, \b( শব্দের সীমানা ) ধন্যবাদ । তালিকা হয়, তাহলে ['apple', 'banana'], এটা শব্দ ঠিক হয় প্রতিস্থাপন করবে appleবা banana, কিন্তু না nana, banaবা pineapple
এরিক ডুমিনিল

15

আপনি যে জিনিসটি চেষ্টা করতে চাইতে পারেন তা হ'ল শব্দটির সীমানা এনকোড করার জন্য বাক্যগুলির প্রাক-প্রক্রিয়াজাতকরণ। মূলত প্রতিটি বাক্যকে শব্দের সীমানায় বিভক্ত করে শব্দের তালিকায় পরিণত করুন।

এটি দ্রুত হওয়া উচিত, কারণ একটি বাক্য প্রক্রিয়া করার জন্য, আপনাকে কেবল প্রতিটি শব্দের মধ্য দিয়ে পদক্ষেপ নিতে হবে এবং এটি মিলছে কিনা তা খতিয়ে দেখতে হবে।

বর্তমানে রেজেক্স অনুসন্ধানটি প্রতিবার পুরো স্ট্রিংয়ের মধ্য দিয়ে আবার শব্দের সীমানা সন্ধান করতে হবে এবং পরবর্তী পাশের আগে এই কাজের ফলাফলটিকে "বাতিল" করবে।


8

ঠিক আছে, এখানে পরীক্ষার সেট সহ একটি দ্রুত এবং সহজ সমাধান।

জয়ী কৌশল:

re.sub ("\ w +", repl, वाक्य) শব্দগুলির সন্ধান করে।

"repl" একটি কলযোগ্য হতে পারে। আমি একটি ফাংশন ব্যবহার করেছি যা ডিক দেখার জন্য কাজ করে এবং ডিকটিতে অনুসন্ধান এবং প্রতিস্থাপনের জন্য শব্দগুলি থাকে।

এটি সর্বাধিক সহজ এবং দ্রুত সমাধান (নীচের কোডের উদাহরণ ফাংশন রিপ্লেশন 4 দেখুন)।

দ্বিতীয় সেরা

ধারণাটি হ'ল বাক্যগুলিকে শব্দের মধ্যে বিভক্ত করা, পুনরায় স্প্লিট ব্যবহার করে বাক্যগুলি পরে পুনর্গঠনের জন্য বিভাজনকারীদের সংরক্ষণ করা। তারপরে, প্রতিস্থাপনগুলি একটি সাধারণ ডিক লুকের সাহায্যে সম্পন্ন হয়।

(উদাহরণস্বরূপ কোডের ফাংশন রিপ্লেজ ৩ দেখুন)।

উদাহরণস্বরূপ কার্যকারণের জন্য সময়:

replace1: 0.62 sentences/s
replace2: 7.43 sentences/s
replace3: 48498.03 sentences/s
replace4: 61374.97 sentences/s (...and 240.000/s with PyPy)

... এবং কোড:

#! /bin/env python3
# -*- coding: utf-8

import time, random, re

def replace1( sentences ):
    for n, sentence in enumerate( sentences ):
        for search, repl in patterns:
            sentence = re.sub( "\\b"+search+"\\b", repl, sentence )

def replace2( sentences ):
    for n, sentence in enumerate( sentences ):
        for search, repl in patterns_comp:
            sentence = re.sub( search, repl, sentence )

def replace3( sentences ):
    pd = patterns_dict.get
    for n, sentence in enumerate( sentences ):
        #~ print( n, sentence )
        # Split the sentence on non-word characters.
        # Note: () in split patterns ensure the non-word characters ARE kept
        # and returned in the result list, so we don't mangle the sentence.
        # If ALL separators are spaces, use string.split instead or something.
        # Example:
        #~ >>> re.split(r"([^\w]+)", "ab céé? . d2eéf")
        #~ ['ab', ' ', 'céé', '? . ', 'd2eéf']
        words = re.split(r"([^\w]+)", sentence)

        # and... done.
        sentence = "".join( pd(w,w) for w in words )

        #~ print( n, sentence )

def replace4( sentences ):
    pd = patterns_dict.get
    def repl(m):
        w = m.group()
        return pd(w,w)

    for n, sentence in enumerate( sentences ):
        sentence = re.sub(r"\w+", repl, sentence)



# Build test set
test_words = [ ("word%d" % _) for _ in range(50000) ]
test_sentences = [ " ".join( random.sample( test_words, 10 )) for _ in range(1000) ]

# Create search and replace patterns
patterns = [ (("word%d" % _), ("repl%d" % _)) for _ in range(20000) ]
patterns_dict = dict( patterns )
patterns_comp = [ (re.compile("\\b"+search+"\\b"), repl) for search, repl in patterns ]


def test( func, num ):
    t = time.time()
    func( test_sentences[:num] )
    print( "%30s: %.02f sentences/s" % (func.__name__, num/(time.time()-t)))

print( "Sentences", len(test_sentences) )
print( "Words    ", len(test_words) )

test( replace1, 1 )
test( replace2, 10 )
test( replace3, 1000 )
test( replace4, 1000 )

সম্পাদনা করুন: আপনি যদি অনুগ্রহের একটি ছোট হাতের তালিকাটি পাস করেন এবং পুনরায় সম্পাদনা সম্পাদনা করেন তা যাচাই করার সময় আপনি ছোট হাতের বিষয়টিও উপেক্ষা করতে পারেন

def replace4( sentences ):
pd = patterns_dict.get
def repl(m):
    w = m.group()
    return pd(w.lower(),w)

1
পরীক্ষাগুলির জন্য উত্সাহ দিন। replace4এবং আমার কোড একই পারফরম্যান্স আছে।
এরিক ডুমিনিল

ডিএফ repl(m):কী করছে এবং আপনি কীভাবে mফাংশনটি অর্পণ করছেন তা নিশ্চিত নন
প্রতিস্থাপন

এছাড়াও আমি error: unbalanced parenthesisলাইনের জন্য ত্রুটি পাচ্ছিpatterns_comp = [ (re.compile("\\b"+search+"\\b"), repl) for search, repl in patterns ]
স্ট্যাটগুয়েসার

রিপ্লেজ ৩ এবং রিপ্লেস ৪ ফাংশন মূল সমস্যাটিকে (শব্দের প্রতিস্থাপনের জন্য) সম্বোধন করার সময়, প্রতিস্থাপন 1 এবং প্রতিস্থাপন 2 আরও সাধারণ-উদ্দেশ্য হিসাবে কাজ করে, যদিও সূচগুলি একটি বাক্য নয় (শব্দের ক্রম) এবং কেবল একটি শব্দ নয় those
জোল্টন ফেদর

7

সম্ভবত পাইথন এখানে সঠিক সরঞ্জাম নয়। ইউনিক্স সরঞ্জামচেন সহ এখানে একটি

sed G file         |
tr ' ' '\n'        |
grep -vf blacklist |
awk -v RS= -v OFS=' ' '{$1=$1}1'

ধরে নিচ্ছি আপনার ব্ল্যাকলিস্ট ফাইলটি শব্দের সীমানা যুক্ত হয়ে প্রিপ্রোসেস করা হয়েছে। পদক্ষেপগুলি হ'ল: ফাইলটিকে দ্বিগুণ ব্যবধানে রূপান্তর করুন, প্রতিটি বাক্যকে প্রতিটি লাইনকে প্রতিটি শব্দের মধ্যে বিভক্ত করুন, ফাইল থেকে কালো তালিকাভুক্ত শব্দগুলি মুছুন, এবং লাইনগুলি আবার মার্জ করুন।

এটি কমপক্ষে একটি আকারের ক্রমটি দ্রুত চালানো উচিত।

শব্দ থেকে ব্ল্যাকলিস্ট ফাইলটি প্রিপ্রোসেস করার জন্য (প্রতি লাইনে একটি শব্দ)

sed 's/.*/\\b&\\b/' words > blacklist

4

এটি সম্পর্কে:

#!/usr/bin/env python3

from __future__ import unicode_literals, print_function
import re
import time
import io

def replace_sentences_1(sentences, banned_words):
    # faster on CPython, but does not use \b as the word separator
    # so result is slightly different than replace_sentences_2()
    def filter_sentence(sentence):
        words = WORD_SPLITTER.split(sentence)
        words_iter = iter(words)
        for word in words_iter:
            norm_word = word.lower()
            if norm_word not in banned_words:
                yield word
            yield next(words_iter) # yield the word separator

    WORD_SPLITTER = re.compile(r'(\W+)')
    banned_words = set(banned_words)
    for sentence in sentences:
        yield ''.join(filter_sentence(sentence))


def replace_sentences_2(sentences, banned_words):
    # slower on CPython, uses \b as separator
    def filter_sentence(sentence):
        boundaries = WORD_BOUNDARY.finditer(sentence)
        current_boundary = 0
        while True:
            last_word_boundary, current_boundary = current_boundary, next(boundaries).start()
            yield sentence[last_word_boundary:current_boundary] # yield the separators
            last_word_boundary, current_boundary = current_boundary, next(boundaries).start()
            word = sentence[last_word_boundary:current_boundary]
            norm_word = word.lower()
            if norm_word not in banned_words:
                yield word

    WORD_BOUNDARY = re.compile(r'\b')
    banned_words = set(banned_words)
    for sentence in sentences:
        yield ''.join(filter_sentence(sentence))


corpus = io.open('corpus2.txt').read()
banned_words = [l.lower() for l in open('banned_words.txt').read().splitlines()]
sentences = corpus.split('. ')
output = io.open('output.txt', 'wb')
print('number of sentences:', len(sentences))
start = time.time()
for sentence in replace_sentences_1(sentences, banned_words):
    output.write(sentence.encode('utf-8'))
    output.write(b' .')
print('time:', time.time() - start)

এই সমাধানগুলি শব্দের সীমানায় বিভক্ত হয় এবং প্রতিটি শব্দকে একটি সেটে দেখায়। সেগুলি শব্দের বিকল্পের (লাইটিজের সমাধান) পুনর্নির্মাণের তুলনায় দ্রুত হওয়া উচিত কারণ এই সমাধানগুলি হ'ল সেট লুপের কারণে এনপুটটির O(n)আকার হয় amortized O(1), যখন রেজেেক্স বিকল্প ব্যবহার করে রেজেক্স ইঞ্জিনকে শব্দের মিলের জন্য পরীক্ষা করতে হবে শুধু শব্দের গণ্ডির চেয়ে প্রতিটি চরিত্রের উপর। আমার সমাধানটি মূল পাঠ্যে ব্যবহৃত শ্বেত স্পেসগুলি সংরক্ষণ করার জন্য অতিরিক্ত যত্ন নিন (যেমন এটি হোয়াইটস্পেসগুলি সংকোচিত করে না এবং ট্যাবগুলি, নিউলাইনগুলি এবং অন্যান্য শ্বেতক্ষেত্রের অক্ষরগুলি সংরক্ষণ করে) তবে আপনি যদি সিদ্ধান্ত নেন যে আপনি এটির যত্ন নেন না, এটি আউটপুট থেকে এগুলি সরাতে মোটামুটি সোজা হওয়া উচিত।

আমি কর্পাস.টিএসটিএস্টে পরীক্ষা করেছি, যা গুটেনবার্গ প্রকল্প থেকে ডাউনলোড করা একাধিক ই-বুকের সংমিশ্রণ, এবং নিষিদ্ধ_ওয়ার্ডস.টিএসটিএসটি 20000 শব্দ এলোমেলোভাবে উবুন্টুর ওয়ার্ডলিস্ট থেকে বাছাই করা হয়েছে (/ মার্কিন / শেয়ার / ডিক / আমেরিকান ইংলিশ)। 862462 টি বাক্য প্রক্রিয়া করতে 30 সেকেন্ড সময় লাগে (এবং পাইপায় এর অর্ধেক)। "" দ্বারা বিচ্ছিন্ন কিছু হিসাবে আমি বাক্যকে সংজ্ঞায়িত করেছি।

$ # replace_sentences_1()
$ python3 filter_words.py 
number of sentences: 862462
time: 24.46173644065857
$ pypy filter_words.py 
number of sentences: 862462
time: 15.9370770454

$ # replace_sentences_2()
$ python3 filter_words.py 
number of sentences: 862462
time: 40.2742919921875
$ pypy filter_words.py 
number of sentences: 862462
time: 13.1190629005

পিপিপি বিশেষত দ্বিতীয় পদ্ধতির থেকে বেশি উপকৃত হয়, যখন সিপিথন প্রথম পদ্ধতির চেয়ে আরও ভাল ছিল। উপরের কোডটি পাইথন 2 এবং 3 উভয় ক্ষেত্রেই কাজ করা উচিত।


পাইথন 3 প্রশ্নে দেওয়া আছে। আমি এটিকে উত্সাহিত করেছি তবে আমি মনে করি এটি কম ভার্বোস করার জন্য এই কোডটিতে কিছু বিশদ বিবরণ এবং 'অনুকূল' প্রয়োগের পক্ষে উত্সর্গ করা উপযুক্ত।
পিভিজি

যদি আমি এটি সঠিকভাবে বুঝতে পারি তবে এটি মূলত আমার উত্তর হিসাবে একই নীতি, তবে আরও ভার্বোস? বিভাজন এবং এর যোগদান \W+মূলত মত হল subউপর \w+, ডান?
এরিক ডুমিনিল

আমি অবাক হয়েছি যদি আমার সমাধান নীচে (ফাংশন রিপ্লেস 4) পাইপির চেয়ে দ্রুত হয়;) আমি আপনার ফাইলগুলিতে পরীক্ষা করতে চাই!
bobflux

3

ব্যবহারিক পদ্ধতির

নীচে বর্ণিত একটি সমাধান একই পাঠ্যটিতে সমস্ত পাঠ্য সংরক্ষণ এবং জটিলতার স্তর হ্রাস করতে প্রচুর মেমরি ব্যবহার করে। র‌্যাম যদি কোনও সমস্যা হয় তবে এটি ব্যবহারের আগে দুবার ভাবেন।

সঙ্গে join/ splitঠাট আপনি সব যা অ্যালগরিদম গতি বাড়াতে উচিত এ লুপ এড়াতে পারবেন।

  • একটি বিশেষ বিস্ময়কর শব্দ যা বাক্য দ্বারা অন্তর্ভুক্ত থাকে তা বাক্যকে সংযুক্ত করুন:
  • merged_sentences = ' * '.join(sentences)

  • |"বা" রেজেক্স স্টেটমেন্ট ব্যবহার করে বাক্য থেকে আপনাকে মুক্তি দেওয়ার জন্য প্রয়োজনীয় সমস্ত শব্দের জন্য একটি একক রেজেক্স সংকলন করুন:
  • regex = re.compile(r'\b({})\b'.format('|'.join(words)), re.I) # re.I is a case insensitive flag

  • সংকলিত রেজেক্সের সাহায্যে শব্দগুলি সাবস্ক্রিপ্ট করুন এবং এটিকে বিশেষ ডিলিমিটার অক্ষর দ্বারা পৃথক বাক্যে আলাদা করুন:
  • clean_sentences = re.sub(regex, "", merged_sentences).split(' * ')

    কর্মক্ষমতা

    "".joinজটিলতা হ'ল ও (এন)। এটি বেশ স্বজ্ঞাত তবে যাইহোক কোনও উত্স থেকে একটি সংক্ষিপ্ত উদ্ধৃতি রয়েছে:

    for (i = 0; i < seqlen; i++) {
        [...]
        sz += PyUnicode_GET_LENGTH(item);

    সুতরাং join/splitআপনার কাছে ও (শব্দ) + ২ * ও (বাক্য) রয়েছে যা প্রাথমিক পদ্ধতির সাথে এখনও লিনিয়ার জটিলতা বনাম 2 * ও (এন 2 )।


    বিটিডব্লিউ মাল্টিথ্রেডিং ব্যবহার করবেন না। জিআইএল প্রতিটি অপারেশন অবরুদ্ধ করবে কারণ আপনার কাজটি কঠোরভাবে সিপিইউ আবদ্ধ তাই জিআইএল মুক্তি পাওয়ার কোনও সুযোগ নেই তবে প্রতিটি থ্রেড একই সাথে টিকগুলি প্রেরণ করবে যা অতিরিক্ত প্রচেষ্টা এবং এমনকি অপারেশনের দিকে পরিচালিত করে।


    যদি বাক্যগুলি কোনও পাঠ্য ফাইলে সংরক্ষণ করা হয় (তবে), সেগুলি একটি নতুন লাইন দ্বারা ইতিমধ্যে পৃথক করা হয়েছে। সুতরাং পুরো ফাইলটি একটি বড় স্ট্রিং (বা বাফার) হিসাবে পড়া যায়, শব্দগুলি সরানো হয় এবং তারপরে আবার লিখিত হয় (বা এটি সরাসরি মেমরি ম্যাপিং ব্যবহার করে ফাইলটিতে করা যেতে পারে)। ওহ, কোনও শব্দ মুছে ফেলতে, বাকী অংশটি বাকী অংশটি শূন্যস্থান পূরণ করতে ফিরে যেতে হবে, যাতে এটি একটি খুব বড় স্ট্রিংয়ের সমস্যা হবে। বিকল্পের মধ্যে শব্দের মধ্যবর্তী অংশগুলি অন্য স্ট্রিং বা ফাইলে (যা নতুনলাইনগুলি অন্তর্ভুক্ত করবে) ফিরে লিখতে হবে - বা কেবল সেই অংশগুলিকে একটি এমএম্যাপ করা ফাইল (1) এ সরানো হবে ..
    ড্যানি_ডেস

    .. এরিক ডুমিনিলের সেট লুকের সাথে মিলিত সেই শেষ পদ্ধতির (শব্দের মধ্যে অংশগুলি মুভিং / লেখার জন্য) সত্যিই দ্রুত হতে পারে, সম্ভবত এমনকি রেজেক্স ব্যবহার না করেই। (2)
    ড্যানি_এসএস

    .. অথবা সম্ভবত একাধিক শব্দের প্রতিস্থাপন করার সময় কেবল রেজিক্স কেবলমাত্র সেই অংশগুলি সরিয়ে নেওয়ার জন্য ইতিমধ্যে অনুকূলিত হয়েছে, আমি জানি না।
    ড্যানি_এসএস

    0

    আপনার সমস্ত বাক্যকে একটি ডকুমেন্টে যুক্ত করুন। আপনার সমস্ত "খারাপ" শব্দ সনাক্ত করতে আহো-করাসিক অ্যালগরিদমের ( এখানে একটি ) কোনও প্রয়োগ প্রয়োগ করুন । ফাইলটি অতিক্রম করুন, প্রতিটি খারাপ শব্দকে প্রতিস্থাপন করুন, পাওয়া শব্দের অফসেটগুলি আপডেট করা ইত্যাদি etc.

    আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
    Licensed under cc by-sa 3.0 with attribution required.