দুটি চিহ্নিতকারীদের মধ্যে কীভাবে সাবস্ট্রাকিং নিষ্কাশন করবেন?


335

ধরা যাক আমার একটি স্ট্রিং আছে 'gfgfdAAA1234ZZZuijjk'এবং আমি কেবল '1234'অংশটি বের করতে চাই ।

আমি কেবলমাত্র জানি আগে কয়েকটি চরিত্রটি সরাসরি কী হবে AAAএবং ZZZঅংশটির পরে আমি আগ্রহী 1234

sedস্ট্রিং দিয়ে এটির মতো কিছু করা সম্ভব:

echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"

এবং এটি আমাকে 1234ফলাফল হিসাবে দেবে ।

পাইথনে একই জিনিস কীভাবে করবেন?

উত্তর:


587

নিয়মিত এক্সপ্রেশন ব্যবহার করে - আরও রেফারেন্সের জন্য ডকুমেন্টেশন

import re

text = 'gfgfdAAA1234ZZZuijjk'

m = re.search('AAA(.+?)ZZZ', text)
if m:
    found = m.group(1)

# found: 1234

বা:

import re

text = 'gfgfdAAA1234ZZZuijjk'

try:
    found = re.search('AAA(.+?)ZZZ', text).group(1)
except AttributeError:
    # AAA, ZZZ not found in the original string
    found = '' # apply your error handling

# found: 1234

20
দ্বিতীয় সমাধানটি আরও ভাল, যদি প্যাটার্নটি বেশিরভাগ সময় মেলে, কারণ অনুমতিের চেয়ে ক্ষমা চাওয়া তার পক্ষে সহজ।
বেনগেট

7
সূচকটি 0 থেকে শুরু হয় না? সুতরাং আপনার গ্রুপ (1) এর পরিবর্তে গ্রুপ (0) ব্যবহার করা দরকার?
আলেকজান্ডার

22
@ আলেকজান্দার, না, গোষ্ঠী (0) পূর্ণ মিলবে স্ট্রিং: AAA1234ZZZ এবং গোষ্ঠী (1) প্রথম গ্রুপের সাথে মিলিত কেবলমাত্র অক্ষরগুলি প্রত্যাবর্তন করবে: 1234
ইউরি কে

1
@ বেঙ্গট: কেন? প্রথম সমাধানটি আমার কাছে বেশ সহজ দেখাচ্ছে এবং এতে কোডের কম লাইন রয়েছে।
হ্যালো গুডবাই

5
এই অভিব্যক্তিতে? অ-লোভী হতে অর্থাত্ সংশোধন করে। এটি 1 থেকে উপরের দিকে যে কোনও সংখ্যক বারের সাথে মিলবে তবে যত কম সম্ভব, কেবল প্রয়োজনীয় হিসাবে প্রসারিত হবে। ? ছাড়া, প্রথম গ্রুপটি জিএফজিএফএএএএএএডএজেডজেকএএএএএ 43 জেডজোনাইফকে 2ZZZkeAAA43 হিসাবে মিলবে, তবে? এটি কেবল 2 এর সাথে মিলবে, তারপরে একাধিক অনুসন্ধান করা (বা এটি বেরিয়ে এসে আবার অনুসন্ধান করা) 43 টির সাথে মিলবে
ডম

113
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'

তারপরে আপনি চাইলে পুনরায় মডিউলটির সাথেও রেগেক্সপস ব্যবহার করতে পারেন, তবে এটি আপনার ক্ষেত্রে প্রয়োজনীয় নয়।


9
প্রশ্নটি বোঝা যাচ্ছে যে ইনপুট পাঠ্যে সর্বদা "এএএ" এবং "জেডজেডজেড" উভয়ই থাকবে। যদি এটি না হয়, আপনার উত্তর মারাত্মকভাবে ব্যর্থ হয় (এর অর্থ এটি খালি স্ট্রিং বা ব্যতিক্রম ছোঁড়ার পরিবর্তে পুরোপুরি কিছু ভুল ফেরায়; ইনপুট স্ট্রিং হিসাবে "হ্যালো সেখানে" ভাবেন) think
tzot

@ user225312 reপদ্ধতিটি কি তবে দ্রুত নয়?
বিভ্রান্ত

1
ভোট, তবে আমি রক্ষণাবেক্ষণের জন্য "s.find ('AAA') + 3" এর পরিবর্তে "x = 'AAA'; s.find (x) + len (x)" ব্যবহার করব।
অ্যালেক্স

1
টোকেন কোনো খুঁজে পাওয়া যাবে না পারেন, তাহলে s, s.findফিরে আসবে -1। স্লাইসিং অপারেটর s[begin:end] এটিকে বৈধ সূচক হিসাবে গ্রহণ করবে এবং অনাকাঙ্ক্ষিত সাবস্ট্রিং ফিরিয়ে দেবে।
ribamar

@ confused00 খোঁজ পুনরায় তুলনায় অনেক দ্রুততর stackoverflow.com/questions/4901523/...
Claudiu Creanga

65

নিয়মিত প্রকাশ

import re

re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)

উপরে AttributeError"এএএ" এবং "জেডজেডজেড" যদি না থাকে তবে উপরোক্ত হিসাবেগুলি ব্যর্থ হবেyour_text

স্ট্রিং পদ্ধতি

your_text.partition("AAA")[2].partition("ZZZ")[0]

"এএএ" বা "জেডজেডজেড" যদি না থাকে তবে উপরেরটি খালি স্ট্রিংটি ফিরিয়ে দেবে your_text

পিএস পাইথন চ্যালেঞ্জ?


6
এই উত্তর সম্ভবত আরও আপ ভোট প্রাপ্য। স্ট্রিং পদ্ধতিটি সবচেয়ে শক্তিশালী উপায়। এটির জন্য / চেষ্টা করে দেখার দরকার নেই।
চেইমজি

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

দুর্দান্ত, অনেক ধন্যবাদ! - এটি স্ট্রিংয়ের জন্য কাজ করে এবং রিজেক্সের প্রয়োজন হয় না
অ্যালেক্স

ঈশ্বর! সত্যিই, বিভাজন! অনেক ধন্যবাদ!
অ্যান্ড্রে ওয়াল


12

অবাক করে দিয়েছি যে কেউই এটি উল্লেখ করেনি যা ওয়ান-অফ স্ক্রিপ্টগুলির জন্য আমার দ্রুত সংস্করণ:

>>> x = 'gfgfdAAA1234ZZZuijjk'
>>> x.split('AAA')[1].split('ZZZ')[0]
'1234'

@ ব্যবহারকারী 1810100 মূলত উল্লেখ করেছেন যে আপনি পোস্ট করার আগের দিনটির প্রায় 5 বছর অবধি ...
জন

10

আপনি কোডের এক লাইন ব্যবহার করে করতে পারেন

>>> import re

>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')

>>> ['1234']

ফলাফল তালিকা পাবেন ...


7

আপনি তার জন্য পুনরায় মডিউল ব্যবহার করতে পারেন :

>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)

5

সেড দিয়ে স্ট্রিং দিয়ে এ জাতীয় কিছু করা সম্ভব:

echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"

এবং এটি আমাকে 1234 ফলাফল হিসাবে দেবে।

আপনি re.subএকই রেজেক্স ব্যবহার করে ফাংশন দিয়ে একই করতে পারে ।

>>> re.sub(r'.*AAA(.*)ZZZ.*', r'\1', 'gfgfdAAA1234ZZZuijjk')
'1234'

বেসিক সেডে, ক্যাপচারিং গ্রুপের প্রতিনিধিত্ব করা হয় \(..\), তবে অজগরটিতে এটি প্রতিনিধিত্ব করেছিল (..)


5

পাইথনে, findallনিয়মিত এক্সপ্রেশন ( re) মডিউলটিতে পদ্ধতি ব্যবহার করে সাবস্ট্রিং ফর্ম স্ট্রিং উত্তোলন করা যায় ।

>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']

4

আপনি আপনার কোডে (অক্ষর সূচক দ্বারা) এই ফাংশনটির সাথে প্রথম সাবস্ট্রিং সন্ধান করতে পারেন। এছাড়াও, আপনি একটি স্ট্রিংয়ের পরে কী তা খুঁজে পেতে পারেন।

def FindSubString(strText, strSubString, Offset=None):
    try:
        Start = strText.find(strSubString)
        if Start == -1:
            return -1 # Not Found
        else:
            if Offset == None:
                Result = strText[Start+len(strSubString):]
            elif Offset == 0:
                return Start
            else:
                AfterSubString = Start+len(strSubString)
                Result = strText[AfterSubString:AfterSubString + int(Offset)]
            return Result
    except:
        return -1

# Example:

Text = "Thanks for contributing an answer to Stack Overflow!"
subText = "to"

print("Start of first substring in a text:")
start = FindSubString(Text, subText, 0)
print(start); print("")

print("Exact substring in a text:")
print(Text[start:start+len(subText)]); print("")

print("What is after substring \"%s\"?" %(subText))
print(FindSubString(Text, subText))

# Your answer:

Text = "gfgfdAAA1234ZZZuijjk"
subText1 = "AAA"
subText2 = "ZZZ"

AfterText1 = FindSubString(Text, subText1, 0) + len(subText1)
BeforText2 = FindSubString(Text, subText2, 0) 

print("\nYour answer:\n%s" %(Text[AfterText1:BeforText2]))



2

আমি যদি কিছু করেছি ঠিক তেমন কাউকে করতে হবে। আমাকে প্রথম লাইনে বন্ধনীর ভিতরে সমস্ত কিছু বের করতে হয়েছিল। উদাহরণস্বরূপ, যদি আমার 'মার্কিন প্রেসিডেন্ট (বারাক ওবামা) এর সাথে সাক্ষাত হয়েছিল ...' এর মতো লাইন থাকে এবং আমি কেবল 'বারাক ওবামা' পেতে চাই তবে এটি সমাধান:

regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'

অর্থাৎ আপনাকে slash \সাইন সহ বন্ধনী বন্ধ করতে হবে । যদিও পাইথন আরও নিয়মিত প্রকাশের বিষয়ে এটি সমস্যা।

এছাড়াও, কিছু ক্ষেত্রে আপনি রেজেক্স সংজ্ঞা দেওয়ার আগে 'আর' চিহ্ন দেখতে পাবেন। যদি আর উপসর্গ না থাকে তবে আপনাকে সি এর মতো পালানোর অক্ষর ব্যবহার করতে হবে এখানে সে সম্পর্কে আরও আলোচনা করা হবে।


2

পাইপার্সিং ব্যবহার করা হচ্ছে

import pyparsing as pp

word = pp.Word(pp.alphanums)

s = 'gfgfdAAA1234ZZZuijjk'
rule = pp.nestedExpr('AAA', 'ZZZ')
for match in rule.searchString(s):
    print(match)

যা ফলন:

[['1234']]


0

এখানে রেজিক্স ছাড়াই একটি সমাধান রয়েছে যা দৃশ্যের জন্যও অ্যাকাউন্ট করে যেখানে প্রথম সাবস্ট্রিংয়ে দ্বিতীয় স্ট্রিং থাকে। দ্বিতীয় চিহ্নিতকারী প্রথম চিহ্নিতকারীর পরে থাকলে এই ক্রিয়াকলাপটি কেবলমাত্র একটি স্ট্রিংিং খুঁজে পাবে।

def find_substring(string, start, end):
    len_until_end_of_first_match = string.find(start) + len(start)
    after_start = string[len_until_end_of_first_match:]
    return string[string.find(start) + len(start):len_until_end_of_first_match + after_start.find(end)]

0

এটি করার আরেকটি উপায় হ'ল তালিকাগুলি ব্যবহার করে (ধরুন আপনি যে সাবস্ট্রিংটি সন্ধান করছেন এটি সংখ্যার তৈরি, কেবল):

string = 'gfgfdAAA1234ZZZuijjk'
numbersList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
output = []

for char in string:
    if char in numbersList: output.append(char)

print(f"output: {''.join(output)}")
### output: 1234

-1

কোনও মিল না থাকলে অন্য স্ট্রিংকে ফিরিয়ে দেয় এমন একটি লাইনার। সম্পাদনা করুন: উন্নত সংস্করণটি nextফাংশন ব্যবহার করে, "not-found"প্রয়োজনে অন্য কিছু দিয়ে প্রতিস্থাপন করুন :

import re
res = next( (m.group(1) for m in [re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk" ),] if m), "not-found" )

এটি করার জন্য আমার অন্যান্য পদ্ধতিটি, কম অনুকূল, দ্বিতীয়বার রিজেক্স ব্যবহার করে, এখনও একটি ছোট্ট উপায় খুঁজে পায়নি:

import re
res = ( ( re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk") or re.search("()","") ).group(1) )
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.