পাইথন রেজেক্স সমস্ত ওভারল্যাপিং মিল খুঁজে পাবে?


101

আমি পাইথন ২.6 এ পুনরায় ব্যবহার করে সংখ্যার বৃহত্তর ধারাবাহিকের মধ্যে প্রতি 10 সংখ্যার সিরিজ সংখ্যার সন্ধান করার চেষ্টা করছি।

আমি সহজে কোনও ওভারল্যাপিং ম্যাচ দখল করতে সক্ষম নই, তবে আমি সংখ্যা সিরিজের প্রতিটি ম্যাচ চাই। যেমন

"123456789123456789" এ

আমার নিম্নলিখিত তালিকা পাওয়া উচিত:

[1234567891,2345678912,3456789123,4567891234,5678912345,6789123456,7891234567,8912345678,9123456789]

আমি "লুকোহেড" এর উল্লেখ পেয়েছি, তবে যে উদাহরণগুলি আমি দেখেছি সেগুলি বৃহত্তর গ্রুপিংয়ের পরিবর্তে কেবল কয়েকটি সংখ্যক সংখ্যা দেখায় এবং আমি দুটি সংখ্যার বাইরেও তাদের রূপান্তর করতে সক্ষম হইনি।


6
উপস্থাপিত সমাধানগুলি কার্যকর হবে না যখন ওভারল্যাপিং ম্যাচগুলি একই বিন্দুতে শুরু হয়, যেমন, "অ্যাবিসিডি" এর সাথে "এ | অ্যাব | অ্যাবসি" মিলে কেবল একটি ফলাফল ফিরে আসবে। এর জন্য কী এমন কোনও সমাধান রয়েছে যা কল করার ম্যাচে () একাধিকবার জড়িত না, ম্যানুয়ালি 'শেষ' সীমানা ট্র্যাক করে?
ভেটর দে আরাজো

@ ভোটারডিআরেজো: ওভারল্যাপিং রিজেক্সগুলি (a|ab|abc)সাধারণত নেস্টেড ক্যাপচার-গ্রুপগুলির সাথে অ-ওভারল্যাপিং হিসাবে আবার লিখতে পারে, উদাহরণস্বরূপ (a(b(c)?)?)?, কোনও ম্যাচ আনপ্যাক করার সময় আমরা বাহ্যিকতম (অর্থাত্ বামদিকের) ক্যাপচার গ্রুপ ব্যতীত সমস্ত কিছু উপেক্ষা করি; অবশ্যই এটি সামান্য বেদনাদায়ক এবং কম সুগঠিত। এটি ম্যাচ করার জন্য আরও পারফরম্যান্ট রেজেক্সও হবে।
smci

উত্তর:


179

লুকোহেডের অভ্যন্তরে ক্যাপচারিং গ্রুপটি ব্যবহার করুন। লুয়াহেড আপনার আগ্রহী পাঠ্যটি ক্যাপচার করে, তবে আসল ম্যাচটি প্রযুক্তিগতভাবে শূন্য-প্রস্থের তলদেশীয় লুকের আগে, সুতরাং ম্যাচগুলি প্রযুক্তিগতভাবে অ-ওভারল্যাপিং হয়:

import re 
s = "123456789123456789"
matches = re.finditer(r'(?=(\d{10}))',s)
results = [int(match.group(1)) for match in matches]
# results: 
# [1234567891,
#  2345678912,
#  3456789123,
#  4567891234,
#  5678912345,
#  6789123456,
#  7891234567,
#  8912345678,
#  9123456789]

4
আমার উত্তরটি এর চেয়ে কমপক্ষে 2 গুণ বেশি দ্রুত is তবে এই সমাধানটি মুশকিল, আমি এটি উত্থাপন করেছি।
equequem

16
ব্যাখ্যা = প্যাটার্নটি অনুসন্ধানের পরিবর্তে (10 সংখ্যা), এটি নিদর্শন অনুসারে যে কোনও কিছুই অনুসন্ধান করে। সুতরাং এটি স্ট্রিংয়ের পজিশন 0, স্ট্রিংয়ের পজিশন 1 এবং আরও খুঁজে পায়। তারপরে এটি গোষ্ঠী (1) দখল করে - ম্যাচের প্যাটার্ন এবং সেগুলির একটি তালিকা তৈরি করে। খুব ঠান্ডা.
তাল ওয়েইস

10
আমি স্ট্যাকওভারফ্লোতে যোগ দিয়েছি, প্রশ্নের উত্তর দিয়েছি এবং আমার খ্যাতি পেয়েছি ঠিক তখনই আমি এই উত্তরটিকে উজ্জীবিত করতে পারি। আমি আপাতত পাইথন ২.৪ এর সাথে আটকে আছি তাই আমি পাইথন 3 এর আরও উন্নত রেজেক্স ফাংশনগুলি ব্যবহার করতে পারি না, এবং এটি কেবলমাত্র উদ্ভট কৌশলগুলির সন্ধান করছিলাম।
TheSoundDefense

4
আপনি কোড আরও ব্যাখ্যা যোগ করতে পারেন। স্ট্যাক ওভারফ্লো অনুসারে এটি উত্তম উপায় নয়, কেবল একটি উত্তরে কোড রয়েছে। এটি অবশ্যই মানুষকে সাহায্য করবে।
অক্ষয় হাজারী

4
এটি সত্যই সহায়ক। ধন্যবাদ: ডি
শ্রীকিরণ

80

আপনি তৃতীয় পক্ষের regexমডিউলও ব্যবহার করে দেখতে পারেন (না re), যা ওভারল্যাপিং ম্যাচগুলিকে সমর্থন করে।

>>> import regex as re
>>> s = "123456789123456789"
>>> matches = re.findall(r'\d{10}', s, overlapped=True)
>>> for match in matches: print(match)  # print match
...
1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

আমি পেয়েছি:TypeError: findall() got an unexpected keyword argument 'overlapped'
কার্স্টেন

@ কার্স্টেন: আপনাকে প্রথমে regexমডিউলটি ইনস্টল করতে হবে :pip install regex
ডেভিড সি

ধন্যবাদ, ধন্যবাদ। আমি ভেবেছি রেজেস ইনস্টল না করা হলে আমি একটি আমদানি ত্রুটি পেয়ে যাব
কার্স্টেন

17

আমি রেজেক্সেসের খুব পছন্দ করি তবে তাদের এখানে দরকার নেই।

কেবল

s =  "123456789123456789"

n = 10
li = [ s[i:i+n] for i in xrange(len(s)-n+1) ]
print '\n'.join(li)

ফলাফল

1234567891
2345678912
3456789123
4567891234
5678912345
6789123456
7891234567
8912345678
9123456789

10
রেজেক্সেস কেবল এখানেই প্রয়োজন নেই কারণ আপনি "সংখ্যার বৃহত্তর সিরিজের মধ্যে" বিশেষ জ্ঞান প্রয়োগ করছেন, তাই আপনি ইতিমধ্যে জানেন যে প্রতিটি অবস্থানই 0 <= i < len(s)-n+110-সংখ্যার ম্যাচ শুরুর গ্যারান্টিযুক্ত। এছাড়াও আমি অনুমান করি যে আপনার কোডটি গতিময় হতে পারে, গতির জন্য কোড-গল্ফের জন্য আকর্ষণীয় হবে।
smci
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.