পাইথন নিষ্কাশন প্যাটার্ন মেলে


129

পাইথন ২.7.১ আমি একটি প্যাটার্নের ভিতরে শব্দগুলি বের করতে পাইথন নিয়মিত প্রকাশ করতে চেষ্টা করছি

আমার কাছে এমন কিছু স্ট্রিং রয়েছে যা দেখতে এমন দেখাচ্ছে

someline abc
someother line
name my_user_name is valid
some more lines

আমি "my_user_name" শব্দটি বের করতে চাই। আমি এরকম কিছু করি

import re
s = #that big string
p = re.compile("name .* is valid", re.flags)
p.match(s) #this gives me <_sre.SRE_Match object at 0x026B6838>

আমি এখন আমার_উজার_নামটি কীভাবে বের করব?

উত্তর:


159

আপনাকে রেইগেক্স থেকে ক্যাপচার করা দরকার। searchপ্যাটার্নটির জন্য, যদি পাওয়া যায় তবে স্ট্রিংটি ব্যবহার করে পুনরুদ্ধার করুন group(index)। ধরে নিচ্ছি বৈধ চেক করা হয়:

>>> p = re.compile("name (.*) is valid")
>>> result = p.search(s)
>>> result
<_sre.SRE_Match object at 0x10555e738>
>>> result.group(1)     # group(1) will return the 1st capture.
                        # group(0) will returned the entire matched text.
'my_user_name'

26
আপনি কি নিশ্চিত যে group(0)এটি প্রথম ম্যাচের জন্য নয় ?
sharshofski

33
দেরীতে হলেও হ্যাঁ এবং না উভয়ই। group(0)মেলে পাঠ্যটি ফেরত দেয়, প্রথম ক্যাপচার গ্রুপ নয়। কোড মন্তব্যটি সঠিক, আপনি মনে হচ্ছে ক্যাপচার গ্রুপগুলি এবং ম্যাচগুলিকে গুলিয়ে ফেলছেন। group(1)প্রথম ক্যাপচার গ্রুপটি প্রদান করে।
অ্যান্ড্রুগু

1
আমি পেয়েছিNameError: name '_' is not defined
ইয়ান জি

আপনার দ্বিতীয় লাইনটি আমার মনে হয় পড়া উচিত _ = p.search(s)। আমি এতে ফলাফল নির্ধারণের উল্লেখ করেছি _কিন্তু কোডটি এটি প্রতিফলিত করে না। আমি _ = p.search(s)যে দ্বিতীয় লাইনের জন্য পরিবর্তিত এবং এটি কাজ করে।
ইয়ান জি

2
@ আইএনজি আমি দুঃখিত, আমি আমার উত্তর আপডেট করব। বিটিডাব্লু, একটি স্ট্যান্ডার্ড পাইথন আরপিএল সহ, শেষ ফলাফলটি একটি বিশেষ ভেরিয়েবল নামে ডাকা হয় _। এটি অন্য কোথাও বৈধ নয়।
আল্ট্রা ইন্স্টিন্ট

57

আপনি মিলে যাওয়া গ্রুপগুলি ব্যবহার করতে পারেন:

p = re.compile('name (.*) is valid')

যেমন

>>> import re
>>> p = re.compile('name (.*) is valid')
>>> s = """
... someline abc
... someother line
... name my_user_name is valid
... some more lines"""
>>> p.findall(s)
['my_user_name']

এখানে আমি সমস্ত দৃষ্টান্ত পাওয়ার re.findallচেয়ে ব্যবহার করি । ব্যবহার করে , আপনাকে ম্যাচ অবজেক্টে গ্রুপ থেকে ডেটা নেওয়া দরকার:re.searchmy_user_namere.search

>>> p.search(s)   #gives a match object or None if no match is found
<_sre.SRE_Match object at 0xf5c60>
>>> p.search(s).group() #entire string that matched
'name my_user_name is valid'
>>> p.search(s).group(1) #first group that match in the string that matched
'my_user_name'

মন্তব্যে উল্লিখিত হিসাবে, আপনি আপনার রেজেক্সকে লোভী করতে চাইতে পারেন:

p = re.compile('name (.*?) is valid')

কেবলমাত্র 'name 'এবং পরবর্তীটির মধ্যে স্টাফ বাছাই করতে ' is valid'(আপনার রেগেক্সকে ' is valid'আপনার গ্রুপে অন্যকে বাছতে দেওয়ার পরিবর্তে) ।


2
এটি একটি লোভহীন ম্যাচ সম্ভব ... (যদি না ব্যবহারকারীর নাম একাধিক শব্দ হতে পারে ...)
জন ক্লিমেটস

@ জোনক্লিমেন্টস - আপনার মানে (.*?)? হ্যাঁ, এটি সম্ভব, যদিও ওপি আমাদের ব্যবহার না করা প্রয়োজন না হলেre.DOTALL
ম্যাগসিলসন

হ্যাঁ - re.findall('name (.*) is valid', 'name jon clements is valid is valid is valid')সম্ভবত কাঙ্ক্ষিত ফলাফল আসবে না ...
জন ক্লিমেটস

এটি পাইথন ২.7.১ এর জন্য কাজ করে না? এটি কেবল একটি প্যাটার্ন অবজেক্টটি প্রিন্ট করে?
কান্নান একনাথ

@ ক্যালমস্টোরম - কোন অংশটি কাজ করে না (আমি পাইথন 2.7.3 এ পরীক্ষা করেছি)? আমি যে অংশটি ব্যবহার করি .groupতা হ'ল আপনি গ্রহণ করা উত্তরের মতোই ...
মিলিলেসন

16

আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন:

import re
s = #that big string
# the parenthesis create a group with what was matched
# and '\w' matches only alphanumeric charactes
p = re.compile("name +(\w+) +is valid", re.flags)
# use search(), so the match doesn't have to happen 
# at the beginning of "big string"
m = p.search(s)
# search() returns a Match object with information about what was matched
if m:
    name = m.group(1)
else:
    raise Exception('name not found')

10

এটি এটিকে কিছুটা খাটো এবং বুঝতে সহজ:

import re
text = '... someline abc... someother line... name my_user_name is valid.. some more lines'
>>> re.search('name (.*) is valid', text).group(1)
'my_user_name'


9

আপনি গোষ্ঠী (সঙ্গে নির্দেশিত ব্যবহার করতে পারেন '('এবং ')'স্ট্রিং এর অংশের ক্যাপচার)। ম্যাচের অবজেক্টের group()পদ্ধতিটি আপনাকে তখন গ্রুপের বিষয়বস্তু দেয়:

>>> import re
>>> s = 'name my_user_name is valid'
>>> match = re.search('name (.*) is valid', s)
>>> match.group(0)  # the entire match
'name my_user_name is valid'
>>> match.group(1)  # the first parenthesized subgroup
'my_user_name'

পাইথন সালে 3.6+ আপনি এটি করতে পারেন সূচক একটি ম্যাচ বস্তুর মধ্যে পরিবর্তে ব্যবহার group():

>>> match[0]  # the entire match 
'name my_user_name is valid'
>>> match[1]  # the first parenthesized subgroup
'my_user_name'

6

গোষ্ঠী ব্যবহার না করে এটি করার একটি উপায় এখানে রয়েছে (পাইথন ৩. 3. বা তার বেশি)

>>> re.search('2\d\d\d[01]\d[0-3]\d', 'report_20191207.xml')[0]
'20191207'

1
এটি পাইথন রেজেক্সকে সম্বোধন করে, তবে ওপি'র নির্দিষ্ট প্রশ্নের সমাধান করে না।
এলেস্টার তানেক জাভাস মিরাজ

তদতিরিক্ত, এটি মূলত 3.6+ সূচীকরণ সিনট্যাক্স উল্লেখ করে বিদ্যমান উত্তরগুলিতে নতুন কিছু যুক্ত করে না।
ইউজিন ইয়ারমশ

3

আপনি ক্যাপচার গ্রুপটিও ব্যবহার করতে পারেন (?P<user>pattern)এবং অভিধানের মতো গোষ্ঠীটি অ্যাক্সেস করতে পারেন match['user']

string = '''someline abc\n
            someother line\n
            name my_user_name is valid\n
            some more lines\n'''

pattern = r'name (?P<user>.*) is valid'
matches = re.search(pattern, str(string), re.DOTALL)
print(matches['user'])

# my_user_name

1

দেখে মনে হচ্ছে আপনি আসলে একটি নাম খুঁজে বের করার চেষ্টা করছেন কেবল কোনও মিল খুঁজে পাচ্ছেন। এই যদি হয় তাহলে, আপনার ম্যাচের জন্য বিঘত ইনডেক্স থাকার সহায়ক এবং আমি ব্যবহার করার প্রস্তাব চাই re.finditer। একটি শর্টকাট হিসাবে, আপনি জানেন যে nameআপনার রেজেক্সের অংশটি দৈর্ঘ্য 5 এবং is validদৈর্ঘ্য 9, সুতরাং নামটি বের করার জন্য আপনি ম্যাচের পাঠ্যটি টুকরো টুকরো করতে পারেন।

দ্রষ্টব্য - আপনার উদাহরণে দেখে মনে sহচ্ছে লাইন ব্রেকগুলির সাথে স্ট্রিং রয়েছে, তাই এটি নীচে ধরে নেওয়া হয়েছে।

## covert s to list of strings separated by line:
s2 = s.splitlines()

## find matches by line: 
for i, j in enumerate(s2):
    matches = re.finditer("name (.*) is valid", j)
    ## ignore lines without a match
    if matches:
        ## loop through match group elements
        for k in matches:
            ## get text
            match_txt = k.group(0)
            ## get line span
            match_span = k.span(0)
            ## extract username
            my_user_name = match_txt[5:-9]
            ## compare with original text
            print(f'Extracted Username: {my_user_name} - found on line {i}')
            print('Match Text:', match_txt)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.