របៀបប្រើម៉ូឌុលកន្សោមធម្មតា Python re (ផ្គូផ្គង ស្វែងរក រង។ល។)

អាជីវកម្ម

ដើម្បីអនុវត្តដំណើរការកន្សោមធម្មតានៅក្នុង Python យើងប្រើម៉ូឌុលឡើងវិញពីបណ្ណាល័យស្តង់ដារ។ វាអនុញ្ញាតឱ្យអ្នកស្រង់ ជំនួស និងបំបែកខ្សែអក្សរដោយប្រើលំនាំកន្សោមធម្មតា។

នៅក្នុងផ្នែកនេះ យើងនឹងពន្យល់ពីមុខងារ និងវិធីសាស្រ្តនៃ re module ជាដំបូង។

  • ការចងក្រងគំរូកន្សោមធម្មតា៖compile()
  • វត្ថុដែលត្រូវគ្នា។
  • ពិនិត្យមើលថាតើការចាប់ផ្តើមនៃខ្សែអក្សរត្រូវគ្នាឬអត់ ស្រង់ចេញ៖match()
  • ពិនិត្យមើលការប្រកួតមិនកំណត់ចំពោះការចាប់ផ្តើមទេ៖search()
  • ពិនិត្យមើលថាតើខ្សែអក្សរទាំងមូលត្រូវគ្នាដែរឬទេ៖fullmatch()
  • ទទួលបានបញ្ជីនៃផ្នែកដែលត្រូវគ្នាទាំងអស់៖findall()
  • ទទួលបានផ្នែកដែលត្រូវគ្នាទាំងអស់ជាអ្នកធ្វើឡើងវិញ៖finditer()
  • ជំនួសផ្នែកដែលត្រូវគ្នា៖sub(),subn()
  • ការបំបែកខ្សែអក្សរជាមួយនឹងលំនាំកន្សោមធម្មតា៖split()

បន្ទាប់ពីនោះ ខ្ញុំនឹងពន្យល់តួអក្សរមេតា (តួអក្សរពិសេស) និងលំដាប់ពិសេសនៃកន្សោមធម្មតាដែលអាចប្រើក្នុងម៉ូឌុលឡើងវិញ។ ជាទូទៅវាគឺជាវាក្យសម្ព័ន្ធកន្សោមធម្មតាស្តង់ដារ ប៉ុន្តែត្រូវប្រយ័ត្នចំពោះការកំណត់ទង់ (ជាពិសេស re.ASCII)។

  • metacharacters កន្សោមធម្មតា លំដាប់ពិសេស និងការព្រមាននៅក្នុង Python
  • ការកំណត់ទង់ជាតិ
    • កំណត់ចំពោះតួអក្សរ ASCII៖re.ASCII
    • មិនប្រកាន់អក្សរតូចធំ៖re.IGNORECASE
    • ផ្គូផ្គងការចាប់ផ្តើម និងចុងបញ្ចប់នៃបន្ទាត់នីមួយៗ៖re.MULTILINE
    • បញ្ជាក់ទង់ជាច្រើន។
  • ការផ្គូផ្គងលោភលន់និងមិនលោភលន់

ចងក្រងលំនាំកន្សោមធម្មតា៖ ចងក្រង()

មានវិធីពីរយ៉ាងដើម្បីដំណើរការកន្សោមធម្មតានៅក្នុងម៉ូឌុលឡើងវិញ។

ដំណើរការជាមួយមុខងារ

ទីមួយគឺជាមុខងារ។re.match(),re.sub()មុខងារ​ដូច​នេះ​គឺ​អាច​ប្រើ​បាន​ដើម្បី​អនុវត្ត​ការ​ស្រង់​ចេញ ការ​ជំនួស និង​ដំណើរការ​ផ្សេង​ទៀត​ដោយ​ប្រើ​លំនាំ​កន្សោម​ធម្មតា។

ព័ត៌មានលម្អិតនៃមុខងារនឹងត្រូវបានពិពណ៌នានៅពេលក្រោយ ប៉ុន្តែនៅក្នុងទាំងអស់នោះ អាគុយម៉ង់ទីមួយគឺខ្សែអក្សរនៃគំរូកន្សោមធម្មតា បន្ទាប់មកខ្សែអក្សរដែលត្រូវដំណើរការជាដើម។ ឧទាហរណ៍ នៅក្នុង re.sub() ដែលអនុវត្តការជំនួស អាគុយម៉ង់ទីពីរគឺជាខ្សែអក្សរជំនួស ហើយអាគុយម៉ង់ទីបីគឺជាខ្សែដែលត្រូវដំណើរការ។

import re

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

ចំណាំថា [a-z] នៅក្នុងលំនាំកន្សោមធម្មតាក្នុងឧទាហរណ៍នេះមានន័យថាតួអក្សរណាមួយពី a ដល់ z (ឧ. [a-z]+ ត្រូវ​នឹង​ខ្សែអក្សរ​ណា​ដែល​សរសេរ​អក្សរ​តូច​មួយ ឬ​ច្រើន​ឡើងវិញ។

. គឺជាតួអក្សរមេតា (តួអក្សរដែលមានអត្ថន័យពិសេស) ហើយត្រូវតែគេចចេញដោយប្រើសញ្ញាសម្គាល់ខាងក្រោយ។

ដោយសារខ្សែអក្សរលំនាំកន្សោមធម្មតាតែងតែប្រើ backslashes ច្រើន វាងាយស្រួលប្រើខ្សែអក្សរឆៅដូចក្នុងឧទាហរណ៍។

ដំណើរការក្នុងវិធីសាស្រ្តនៃវត្ថុលំនាំកន្សោមធម្មតា។

វិធីទីពីរដើម្បីដំណើរការកន្សោមធម្មតានៅក្នុងម៉ូឌុលឡើងវិញគឺជាវិធីសាស្ត្រវត្ថុគំរូកន្សោមធម្មតា។

ដោយប្រើ re.compile() អ្នកអាចចងក្រងខ្សែអក្សរលំនាំកន្សោមធម្មតា ដើម្បីបង្កើតវត្ថុគំរូកន្សោមធម្មតា។

p = re.compile(r'([a-z]+)@([a-z]+)\.com')

print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')

print(type(p))
# <class 're.Pattern'>

re.match(),re.sub()ឧទាហរណ៍ ដំណើរការដូចគ្នាទៅនឹងមុខងារទាំងនេះអាចត្រូវបានប្រតិបត្តិជាវិធីសាស្រ្ត match(),sub() នៃវត្ថុកន្សោមធម្មតា។

m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

មុខងារ re.xxx() ទាំងអស់ដែលបានពិពណ៌នាខាងក្រោមក៏ត្រូវបានផ្តល់ជាវិធីសាស្រ្តនៃវត្ថុកន្សោមធម្មតា។

ប្រសិនបើអ្នកកំពុងដំណើរការឡើងវិញនូវដំណើរការដែលប្រើលំនាំដូចគ្នា វាកាន់តែមានប្រសិទ្ធភាពក្នុងការបង្កើតវត្ថុកន្សោមធម្មតាជាមួយ re.compile() ហើយប្រើវាជុំវិញ។

នៅក្នុងកូដគំរូខាងក្រោម អនុគមន៍ត្រូវបានប្រើដោយមិនចងក្រងដើម្បីភាពងាយស្រួល ប៉ុន្តែប្រសិនបើអ្នកចង់ប្រើលំនាំដដែលដដែលៗ វាត្រូវបានណែនាំឱ្យចងក្រងវាជាមុន ហើយប្រតិបត្តិវាជាវិធីសាស្ត្រនៃវត្ថុកន្សោមធម្មតា។

វត្ថុដែលត្រូវគ្នា។

match(), search() ។ល។ ត្រឡប់វត្ថុដែលត្រូវគ្នា។

s = 'aaa@xxx.com'

m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(m))
# <class 're.Match'>

ខ្សែអក្សរ និងទីតាំងដែលត្រូវគ្នាត្រូវបានទទួលដោយប្រើវិធីសាស្ត្រខាងក្រោមនៃវត្ថុដែលត្រូវគ្នា។

  • ទទួលបានទីតាំងនៃការប្រកួត៖start(),end(),span()
  • ទទួលបានខ្សែដែលត្រូវគ្នា៖group()
  • ទទួលបានខ្សែអក្សរសម្រាប់ក្រុមនីមួយៗ៖groups()
print(m.start())
# 0

print(m.end())
# 11

print(m.span())
# (0, 11)

print(m.group())
# aaa@xxx.com

ប្រសិនបើអ្នកភ្ជាប់ផ្នែកមួយនៃគំរូកន្សោមធម្មតានៅក្នុងខ្សែអក្សរដែលមានវង់ក្រចក() ផ្នែកនឹងត្រូវបានដំណើរការជាក្រុម។ ក្នុងករណីនេះ ខ្សែនៃផ្នែកដែលត្រូវគ្នានឹងក្រុមនីមួយៗក្នុងក្រុម() អាចទទួលបានជា tuple ។

m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.groups())
# ('aaa', 'xxx', 'com')

ពិនិត្យមើលថាតើការចាប់ផ្តើមនៃខ្សែអក្សរត្រូវគ្នាឬអត់ ស្រង់ចេញ៖ match()

match() ត្រឡប់វត្ថុដែលត្រូវគ្នា ប្រសិនបើការចាប់ផ្តើមនៃខ្សែអក្សរត្រូវគ្នានឹងលំនាំ។

ដូចដែលបានរៀបរាប់ខាងលើ វត្ថុផ្គូផ្គងអាចត្រូវបានប្រើដើម្បីស្រង់ខ្សែអក្សររងដែលត្រូវគ្នា ឬគ្រាន់តែពិនិត្យមើលថាតើការផ្គូផ្គងមួយត្រូវបានធ្វើឡើងឬអត់។

match() នឹងពិនិត្យតែការចាប់ផ្តើមប៉ុណ្ណោះ។ ប្រសិនបើមិនមានខ្សែអក្សរដែលត្រូវគ្នានៅដើមទេ វាត្រឡប់គ្មាន។

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None

ពិនិត្យ​មើល​ការ​ផ្គូផ្គង​មិន​កំណត់​ចំពោះ​ការ​ចាប់​ផ្តើម​ឡើយ ស្រង់​ចេញ៖ search()

ដូចជា match() វាត្រឡប់វត្ថុដែលត្រូវគ្នាប្រសិនបើវាត្រូវគ្នា។

ប្រសិនបើមានផ្នែកផ្គូផ្គងច្រើន មានតែផ្នែកដែលត្រូវគ្នាដំបូងប៉ុណ្ណោះដែលនឹងត្រូវប្រគល់មកវិញ។

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

ប្រសិនបើអ្នកចង់ទទួលបានផ្នែកដែលត្រូវគ្នាទាំងអស់ សូមប្រើ findall() ឬ finditer() ដូចដែលបានពិពណ៌នាខាងក្រោម។

ពិនិត្យមើលថាតើខ្សែអក្សរទាំងមូលត្រូវគ្នាដែរឬទេ៖ fullmatch()

ដើម្បីពិនិត្យមើលថាតើខ្សែអក្សរទាំងមូលត្រូវគ្នានឹងលំនាំកន្សោមធម្មតា សូមប្រើ fullmatch()។ នេះមានប្រយោជន៍ ជាឧទាហរណ៍ ដើម្បីពិនិត្យមើលថាតើខ្សែអក្សរមួយមានសុពលភាពជាអាសយដ្ឋានអ៊ីមែលឬអត់។

ប្រសិនបើខ្សែអក្សរទាំងមូលត្រូវគ្នា វត្ថុដែលត្រូវគ្នានឹងត្រលប់មកវិញ។

s = 'aaa@xxx.com'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

ប្រសិនបើមានផ្នែកដែលមិនផ្គូផ្គង (គ្រាន់តែផ្គូផ្គងផ្នែកខ្លះ ឬគ្មានការផ្គូផ្គងទាំងអស់) គ្មានផ្នែកណាមួយត្រូវបានត្រឡប់មកវិញទេ។

s = '!!!aaa@xxx.com!!!'

m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None

fullmatch() ត្រូវបានបន្ថែមនៅក្នុង Python 3.4។ ប្រសិនបើអ្នកចង់ធ្វើដូចគ្នានៅក្នុងកំណែមុន សូមប្រើ match() និងតួអក្សរមេតាដែលត្រូវគ្នា $ នៅចុងបញ្ចប់។ ប្រសិនបើខ្សែអក្សរទាំងមូលពីដើមដល់ចប់មិនត្រូវគ្នា វាត្រឡប់គ្មាន។

s = '!!!aaa@xxx.com!!!'

m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None

ទទួលបានបញ្ជីនៃផ្នែកដែលត្រូវគ្នាទាំងអស់៖ findall()

findall() ត្រឡប់បញ្ជីនៃខ្សែរងដែលត្រូវគ្នាទាំងអស់។ ចំណាំថាធាតុនៃបញ្ជីមិនមែនជាវត្ថុដែលត្រូវគ្នាទេ ប៉ុន្តែជាខ្សែអក្សរ។

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']

ចំនួននៃផ្នែកដែលត្រូវគ្នាអាចត្រូវបានពិនិត្យដោយប្រើមុខងារដែលភ្ជាប់មកជាមួយ len() ដែលត្រឡប់ចំនួនធាតុនៅក្នុងបញ្ជី។

print(len(result))
# 3

ការដាក់ជាក្រុមជាមួយនឹងវង់ក្រចក() នៅក្នុងលំនាំកន្សោមធម្មតា ត្រឡប់បញ្ជីនៃ tuples ដែលធាតុទាំងនោះជាខ្សែនៃក្រុមនីមួយៗ។ នេះគឺស្មើនឹងក្រុម() នៅក្នុងវត្ថុដែលត្រូវគ្នា។

result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]

វង់ក្រចកក្រុម () អាចដាក់ក្នុងវង់ក្រចក ដូច្នេះប្រសិនបើអ្នកចង់ទទួលបានការប្រកួតទាំងមូលផងដែរ គ្រាន់តែភ្ជាប់ការប្រកួតទាំងមូលនៅក្នុងវង់ក្រចក ()។

result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]

ប្រសិនបើរកមិនឃើញការផ្គូផ្គងទេ នោះ tuple ទទេនឹងត្រលប់មកវិញ។

result = re.findall('[0-9]+', s)
print(result)
# []

ទទួលបានផ្នែកដែលត្រូវគ្នាទាំងអស់ជាអ្នកធ្វើឡើងវិញ៖ finditer()

finditer() ត្រឡប់ផ្នែកដែលត្រូវគ្នាទាំងអស់ជាអ្នកធ្វើឡើងវិញ។ ធាតុមិនមែនជាខ្សែអក្សរដូចជា findall() ប៉ុន្តែត្រូវគ្នានឹងវត្ថុ ដូច្នេះអ្នកអាចទទួលបានទីតាំង (សន្ទស្សន៍) នៃផ្នែកដែលត្រូវគ្នា។

អក្សរកាត់ខ្លួនវាមិនអាចត្រូវបានបោះពុម្ពចេញដោយ print() ដើម្បីទទួលបានមាតិការបស់វា។ ប្រសិនបើអ្នកប្រើមុខងារដែលភ្ជាប់មកជាមួយ next() ឬសម្រាប់សេចក្តីថ្លែងការណ៍ អ្នកអាចទទួលបានមាតិកាម្តងមួយៗ។

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>

print(type(result))
# <class 'callable_iterator'>

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

វាក៏អាចបំប្លែងទៅជាបញ្ជីដែលមាន list() ផងដែរ។

l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]

print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(type(l[0]))
# <class 're.Match'>

print(l[0].span())
# (0, 11)

ប្រសិនបើអ្នកចង់ទទួលបានទីតាំងនៃផ្នែកដែលត្រូវគ្នាទាំងអស់នោះ ការកំណត់ការយល់ក្នុងបញ្ជីគឺងាយស្រួលជាង list()។

print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]

អ្នកបង្វែរធាតុតាមលំដាប់លំដោយ។ ចំណាំថាប្រសិនបើអ្នកព្យាយាមទាញយកធាតុបន្ថែមទៀតបន្ទាប់ពីឈានដល់ទីបញ្ចប់ អ្នកនឹងលែងមានអ្វីទាំងអស់។

result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)

for m in result:
    print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>

print(list(result))
# []

ជំនួសផ្នែកដែលត្រូវគ្នា៖ sub(), subn()

ដោយប្រើ sub() អ្នកអាចជំនួសផ្នែកដែលត្រូវគ្នាជាមួយនឹងខ្សែអក្សរផ្សេងទៀត។ ខ្សែអក្សរដែលបានជំនួសនឹងត្រូវបានត្រឡប់មកវិញ។

s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net

print(type(result))
# <class 'str'>

នៅពេលដាក់ជាក្រុមជាមួយវង់ក្រចក() ខ្សែអក្សរដែលត្រូវគ្នាអាចត្រូវបានប្រើនៅក្នុងខ្សែអក្សរដែលបានជំនួស។

តាមលំនាំដើម ចំណុចខាងក្រោមត្រូវបានគាំទ្រ៖ ចំណាំថាសម្រាប់ខ្សែធម្មតាដែលមិនមែនជាខ្សែអក្សរដើម សញ្ញាថយក្រោយត្រូវតែត្រូវបានរាយបញ្ជីនៅពីមុខ backslash ដើម្បីគេចពី backslash ។

\1វង់ក្រចកទីមួយ
\2វង់ក្រចកទីពីរ
\3វង់ក្រចកទីបី
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

?P<xxx>
ប្រសិនបើអ្នកដាក់ឈ្មោះក្រុមដោយសរសេរវានៅដើមវង់ក្រចកនៃគំរូកន្សោមធម្មតា អ្នកអាចបញ្ជាក់វាដោយប្រើឈ្មោះជំនួសឱ្យលេខដូចបានបង្ហាញខាងក្រោម។
\g<xxx>

result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net

ចំនួនអាគុយម៉ង់បញ្ជាក់ចំនួនអតិបរមានៃការជំនួស។ មានតែការរាប់ពីផ្នែកខាងឆ្វេងប៉ុណ្ណោះនឹងត្រូវបានជំនួស។

result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net

subn() ត្រឡប់ tuple នៃខ្សែអក្សរដែលបានជំនួស (ដូចគ្នានឹងតម្លៃត្រឡប់នៃ sub()) និងចំនួននៃផ្នែកជំនួស (ចំនួនដែលត្រូវនឹងលំនាំ)។

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)

វិធីសាស្រ្តនៃការបញ្ជាក់អាគុយម៉ង់គឺដូចគ្នានឹង sub() ។ អ្នកអាចប្រើផ្នែកដែលដាក់ជាក្រុមដោយវង់ក្រចក ឬបញ្ជាក់ចំនួនអាគុយម៉ង់។

result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)

result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)

ការបំបែកខ្សែអក្សរជាមួយនឹងលំនាំកន្សោមធម្មតា៖ split()

split() បំបែក​ខ្សែអក្សរ​នៅ​ផ្នែក​ដែល​ត្រូវ​នឹង​លំនាំ ហើយ​ត្រឡប់​វា​ជា​បញ្ជី។

ចំណាំថាការផ្គូផ្គងដំបូង និងចុងក្រោយនឹងមានខ្សែទទេនៅដើម និងចុងបញ្ចប់នៃបញ្ជីលទ្ធផល។

s = '111aaa222bbb333'

result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']

result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']

អាគុយម៉ង់ maxsplit បញ្ជាក់ចំនួនអតិបរមានៃការបំបែក (បំណែក) ។ មានតែការរាប់ពីផ្នែកខាងឆ្វេងប៉ុណ្ណោះដែលនឹងត្រូវបំបែក។

result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']

metacharacters កន្សោមធម្មតា លំដាប់ពិសេស និងការព្រមាននៅក្នុង Python

តួអក្សរមេតាកន្សោមធម្មតាចម្បង (តួអក្សរពិសេស) និងលំដាប់ពិសេសដែលអាចប្រើក្នុងម៉ូឌុល Python 3 re មានដូចខាងក្រោម

តួអក្សរមេតាមាតិកា
.តួអក្សរតែមួយក្រៅពីបន្ទាត់ថ្មី (រួមទាំងបន្ទាត់ថ្មីដែលមានទង់ DOTALL)
^ការចាប់ផ្តើមនៃខ្សែអក្សរ (ក៏ត្រូវគ្នានឹងការចាប់ផ្តើមនៃបន្ទាត់នីមួយៗដែលមានទង់ MULTILINE)
$ចុងបញ្ចប់នៃខ្សែអក្សរ (ក៏ត្រូវគ្នានឹងចុងបញ្ចប់នៃបន្ទាត់នីមួយៗដែលមានទង់ MULTILINE)
*ធ្វើលំនាំមុនម្តងទៀតច្រើនជាង 0 ដង
+ធ្វើលំនាំមុនម្តងទៀតយ៉ាងហោចណាស់ម្តង។
?ធ្វើម្តងទៀតនូវលំនាំមុន 0 ឬ 1 ដង
{m}ធ្វើម្តងទៀតនូវលំនាំមុន m ដង
{m, n}លំនាំចុងក្រោយ។m~nធ្វើម្តងទៀត
[]សំណុំនៃតួអក្សរ[]ផ្គូផ្គងតួអក្សរណាមួយក្នុងចំណោមតួអក្សរទាំងនេះ
|A|Bផ្គូផ្គងលំនាំ A ឬ B
លំដាប់ពិសេសមាតិកា
\dលេខទសភាគយូនីកូដ (កំណត់ត្រឹមលេខ ASCII ដោយទង់ ASCII)
\D\dមានន័យផ្ទុយពីនេះ។
\sតួអក្សរដកឃ្លាយូនីកូដ (កំណត់ចំពោះតួអក្សរដកឃ្លា ASCII ដោយទង់ ASCII)
\S\sមានន័យផ្ទុយពីនេះ។
\wអក្សរ​យូនីកូដ និង​សញ្ញា​គូស​ក្រោម (កំណត់​ចំពោះ​តួ​អក្សរ​លេខ ASCII និង​សញ្ញា​គូស​ក្រោម​ដោយ​ទង់ ASCII)
\W\wមានន័យផ្ទុយពីនេះ។

មិនមែនពួកគេទាំងអស់ត្រូវបានរាយក្នុងតារាងនេះទេ។ សូមមើលឯកសារផ្លូវការសម្រាប់បញ្ជីពេញលេញ។

សូមចំណាំផងដែរថា អត្ថន័យខ្លះមានភាពខុសគ្នានៅក្នុង Python 2 ។

ការកំណត់ទង់ជាតិ

ដូចដែលបានបង្ហាញក្នុងតារាងខាងលើ តួអក្សរមេតាមួយចំនួន និងលំដាប់ពិសេសផ្លាស់ប្តូររបៀបរបស់វាអាស្រ័យលើទង់។

មានតែទង់ជាតិសំខាន់ៗប៉ុណ្ណោះដែលត្រូវបានគ្របដណ្តប់នៅទីនេះ។ សូមមើលឯកសារផ្លូវការសម្រាប់នៅសល់។

កំណត់ចំពោះតួអក្សរ ASCII៖ re.ASCII

\wវា​ក៏​នឹង​ត្រូវ​គ្នា​នឹង​អក្សរ​ខនជី​ទ្វេ​បៃ អក្សរ​លេខ​ជាដើម​តាម​លំនាំដើម​សម្រាប់​ខ្សែអក្សរ Python 3។ វា​មិន​ស្មើ​នឹង​ពាក្យ​ខាងក្រោម​ទេ ព្រោះ​វា​មិន​មែន​ជា​កន្សោម​ធម្មតា​ស្តង់ដារ។[a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None

ប្រសិនបើអ្នកបញ្ជាក់ re.ASCII សម្រាប់ទង់អាគុយម៉ង់នៅក្នុងមុខងារនីមួយៗ ឬបន្ថែមទង់ក្នុងជួរខាងក្រោមទៅដើមនៃខ្សែអក្សរលំនាំកន្សោមធម្មតា វានឹងផ្គូផ្គងតែតួអក្សរ ASCII ប៉ុណ្ណោះ (វានឹងមិនត្រូវគ្នានឹងទ្វេបៃជាភាសាជប៉ុន អក្សរក្រមលេខ ។ល។ .)
(?a)
ក្នុងករណីនេះ ពីរខាងក្រោមគឺសមមូល។
\w#ERROR![a-zA-Z0-9_]

m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None

m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None

ដូចគ្នានេះដែរអនុវត្តនៅពេលចងក្រងជាមួយ re.compile() ។ ប្រើទង់អាគុយម៉ង់ ឬទង់ក្នុងជួរ។

p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)

print(p.match('漢字ABC123'))
# None

ASCII ក៏មានផងដែរជាទម្រង់ខ្លី។ A. អ្នកអាចប្រើទាំង។

print(re.ASCII is re.A)
# True

\W ដែលផ្ទុយពី \W ក៏ត្រូវបានប៉ះពាល់ផងដែរដោយ re.ASCII និងទង់ក្នុងជួរ។

m = re.match(r'\W+', '漢字ABC123')
print(m)
# None

m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>

ដូចនឹង \w ពីរខាងក្រោមត្រូវគ្នាទាំងតួអក្សរមួយបៃ និងពីរបៃតាមលំនាំដើម ប៉ុន្តែត្រូវបានកំណត់ចំពោះតួអក្សរតែមួយបៃ ប្រសិនបើ re.ASCII ឬទង់ក្នុងជួរត្រូវបានបញ្ជាក់។

  • ផ្គូផ្គងលេខ\d
  • ផ្គូផ្គងចន្លោះទទេ\s
  • ផ្គូផ្គងមិនមែនលេខ\D
  • ផ្គូផ្គងគ្មានចន្លោះ។\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>

m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None

m = re.match(r'\s+', ' ')  # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>

m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None

មិនប្រកាន់អក្សរតូចធំ៖re.IGNORECASE

តាមលំនាំដើម វាជាអក្សរតូចធំ។ ដើម្បីផ្គូផ្គងទាំងពីរ អ្នកត្រូវបញ្ចូលទាំងអក្សរធំ និងអក្សរតូចនៅក្នុងលំនាំ។

re.IGNORECASEប្រសិនបើវាត្រូវបានបញ្ជាក់ វានឹងផ្គូផ្គងករណីដែលមិនប្រកាន់អក្សរតូចធំ។ ស្មើនឹងទង់ i នៅក្នុងកន្សោមធម្មតាស្តង់ដារ។

m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>

អ្នកអាចប្រើតិចជាង ឬស្មើ។

  • ទង់ជាតិក្នុងជួរ(?i)
  • អក្សរកាត់re.I

ផ្គូផ្គងការចាប់ផ្តើម និងចុងបញ្ចប់នៃបន្ទាត់នីមួយៗ៖re.MULTILINE

^តួអក្សរមេតានៅក្នុងកន្សោមធម្មតានេះត្រូវគ្នានឹងការចាប់ផ្តើមនៃខ្សែអក្សរ។

តាមលំនាំដើម មានតែការចាប់ផ្តើមនៃខ្សែអក្សរទាំងមូលប៉ុណ្ណោះដែលត្រូវបានផ្គូផ្គង ប៉ុន្តែខាងក្រោមនេះនឹងផ្គូផ្គងការចាប់ផ្តើមនៃបន្ទាត់នីមួយៗផងដែរ។ ស្មើនឹងទង់ m ក្នុងកន្សោមធម្មតាស្តង់ដារ។
re.MULTILINE

s = '''aaa-xxx
bbb-yyy
ccc-zzz'''

print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz

result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']

result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']

result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']

$ផ្គូផ្គងចុងបញ្ចប់នៃខ្សែអក្សរ។ តាមលំនាំដើម មានតែចុងបញ្ចប់នៃខ្សែអក្សរទាំងមូលប៉ុណ្ណោះដែលត្រូវបានផ្គូផ្គង។
re.MULTILINEប្រសិនបើអ្នកបញ្ជាក់ចំណុចនេះ វាក៏នឹងផ្គូផ្គងចុងបញ្ចប់នៃបន្ទាត់នីមួយៗផងដែរ។

result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']

result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']

អ្នកអាចប្រើតិចជាង ឬស្មើ។

  • ទង់ជាតិក្នុងជួរ(?m)
  • អក្សរកាត់re.M

បញ្ជាក់ទង់ជាច្រើន។

|ប្រសិនបើអ្នកចង់បើកទង់ច្រើនក្នុងពេលតែមួយ សូមប្រើវា។ ក្នុង​ករណី​ទង់​ក្នុង​ជួរ តួអក្សរ​នីមួយៗ​ត្រូវ​តែ​តាម​ដោយ​អក្សរ​ដូច​បង្ហាញ​ខាង​ក្រោម។
(?am)

s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''

print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz

result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']

result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']

result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']

ការផ្គូផ្គងលោភលន់និងមិនលោភលន់

នេះគឺជាបញ្ហាទូទៅជាមួយនឹងកន្សោមធម្មតា មិនមែនគ្រាន់តែជាបញ្ហាជាមួយ Python នោះទេ ប៉ុន្តែខ្ញុំនឹងសរសេរអំពីវាព្រោះវាមានទំនោរធ្វើឱ្យខ្ញុំមានបញ្ហា។

តាមលំនាំដើម ខាងក្រោមនេះគឺជាការផ្គូផ្គងលោភលន់ ដែលផ្គូផ្គងខ្សែអក្សរដែលវែងបំផុតដែលអាចធ្វើទៅបាន។

  • *
  • +
  • ?
s = 'aaa@xxx.com, bbb@yyy.com'

m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>

print(m.group())
# aaa@xxx.com, bbb@yyy.com

នេះ? បន្ទាប់​ពី​វា​នឹង​មាន​លទ្ធផល​ក្នុង​ការ​ប្រកួត​តិចតួច​បំផុត​ដែល​មិន​លោភលន់ ដោយ​ត្រូវ​គ្នា​នឹង​ខ្សែ​ខ្លី​ដែល​អាច​ធ្វើ​ទៅ​បាន​។

  • *?
  • +?
  • ??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>

print(m.group())
# aaa@xxx.com

ចំណាំថាការផ្គូផ្គងលោភលន់លំនាំដើមអាចត្រូវគ្នានឹងខ្សែអក្សរដែលមិនបានរំពឹងទុក។

Copied title and URL