|
222 | 222 | >>> match.groups() |
223 | 223 | ('Jazz', 'Rock', 'Pop') |
224 | 224 |
|
225 | | - >>> match.expand('-->\1---->\2------>\3') # Wrong result!!! |
| 225 | + >>> match.expand('-->\1---->\2------>\3') # Warning!!! |
226 | 226 | '-->\x01---->\x02------>\x03' |
227 | 227 |
|
228 | 228 | >>> match.expand('-->\\1---->\\2------>\\3') |
|
232 | 232 | '-->Jazz---->Rock------>Pop' |
233 | 233 |
|
234 | 234 |
|
| 235 | + :: |
| 236 | + |
| 237 | + # \1, \2 and \3 are all valid escape characters |
| 238 | + |
| 239 | + \1 # (U+0001 or 0x01) stands for the ascii start-of-heading character |
| 240 | + \2 # (U+0002 or 0x02) stands for the ascii start-of-text character |
| 241 | + \3 # (U+0003 or 0x03) stands for the ascii end-of-text character |
| 242 | + |
235 | 243 | .. note:: |
236 | 244 | در نمونه کد بالا، خروجی نخستین استفاده از متد ``expand`` متناسب با انتظار نیست، دلیل هم مربوط به وجود کاراکترهایی با ``\`` است (escape characters) که باعث بروز اخلال در تحلیل رشته قالب شده است. بهتر است همیشه در این مواقع از قوانین **raw string** پیروی نماییم: استفاده از ``\\`` به جای ``\`` (همانند ``n\\``) یا قرار دادن یک کاراکتر ``r`` یا ``R`` در ابتدای رشته (همانند ``'r'\n``). در این صورت کاراکترهایی همچون newline یا ``n\`` در رشته، معنای خود را از دست میدهند. (یادآوری از درس هفتم) |
237 | 245 |
|
| 246 | + در واقع مفسر پایتون پیش از قراردادن متن مورد نظر ما در قالب یک شی رشته (string) در حافظه (memory) آن را تحلیل و مقادیر متناسب با کاراکترهای ``\`` را در آن جایگذاری میکند که این کار ممکن است در هنگام استفاده ماژول ``re`` از آن شی رشته اخلال ایجاد کند. استفاده از **raw string** باعث میشود مفسر پایتون متن مورد نظر را بدون تغییر در حافطه قرار دهد. |
| 247 | + |
238 | 248 |
|
239 | 249 | .. tip:: |
240 | 250 | بلای Backslash [`اسناد پایتون <https://docs.python.org/3/howto/regex.html#the-backslash-plague>`__] |
241 | 251 |
|
242 | | - همیشه در هنگام کار با RegEx (نه فقط در زبان پایتون!) مواظب escape characters یا backslash characters باشید. |
| 252 | + همیشه در هنگام کار با RegEx (نه فقط در زبان پایتون!) مواظب escape characters یا همان backslash characters باشید. تا این لحظه برای جلوگیری از پیچیدگی در مثالهای ارائه شده مبحث RegEx از قرار دادن **raw string** صرف نظر شده بود اما از آنجا که الگوهای RegEx پر از ``\`` است همواره میبایست به لزوم استفاده از **raw string** فکر کنیم. |
243 | 253 |
|
244 | 254 | :: |
245 | 255 |
|
246 | | - >>> match = re.search('(?P<num>\d+)', 'Top 100 songs') |
| 256 | + >>> match = re.search(r'(?P<num>\d+)', 'Top 100 songs') |
247 | 257 | >>> match.group(1) |
248 | 258 | '100' |
249 | 259 |
|
250 | | - >>> match.expand('--- \g<num> ---') |
| 260 | + >>> match.expand(r'--- \g<num> ---') |
251 | 261 | '--- 100 ---' |
252 | | - >>> match.expand('--- \g<1> ---') |
| 262 | + >>> match.expand(r'--- \g<1> ---') |
253 | 263 | '--- 100 ---' |
254 | 264 |
|
255 | 265 |
|
|
272 | 282 |
|
273 | 283 | :: |
274 | 284 |
|
275 | | - >>> match = re.search("(\d+)\.(\d+)", "24.1632") |
| 285 | + >>> match = re.search(r"(\d+)\.(\d+)", "24.1632") |
276 | 286 |
|
277 | 287 | >>> match.start() |
278 | 288 | 0 |
|
295 | 305 |
|
296 | 306 | این متد یک شی تاپل دوتایی از خروجی دو متد ``start`` و ``end`` را بر میگرداند و همانند آنها نیز یک آرگومان اختیاری دارد - نمونه خروجی: ``(m.start(group), m.end(group))``:: |
297 | 307 |
|
298 | | - >>> match = re.search("(\d+)\.(\d+)", "24.1632") |
| 308 | + >>> match = re.search(r"(\d+)\.(\d+)", "24.1632") |
299 | 309 | >>> match.span() |
300 | 310 | (0, 7) |
301 | 311 | >>> match.span(1) |
|
325 | 335 |
|
326 | 336 | :: |
327 | 337 |
|
328 | | - >>> match = re.search("(\d+)\.(\d+)", "24.1632") |
| 338 | + >>> match = re.search(r"(\d+)\.(\d+)", "24.1632") |
329 | 339 |
|
330 | 340 | >>> match.re |
331 | 341 | re.compile('(\\d+)\\.(\\d+)') |
|
334 | 344 | '24.1632' |
335 | 345 |
|
336 | 346 |
|
| 347 | +تابع ``match`` |
| 348 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 349 | + |
| 350 | + |
| 351 | +``match(pattern, string, flags=0)`` |
| 352 | + |
| 353 | +تابع ``match`` از ابتدای string انطباق pattern را انجام میدهد، در صورت موفقیت یک شی ``Match`` و در غیر این صورت ``None`` برمیگرداند [`اسناد پایتون <https://docs.python.org/3/library/re.html#re.match>`__]:: |
| 354 | + |
| 355 | + >>> import re # Python 3.x |
| 356 | + |
| 357 | + >>> match = re.match(r'\d+', '123@USERNAME') |
| 358 | + >>> print(match) |
| 359 | + <re.Match object; span=(0, 3), match='123'> |
| 360 | + |
| 361 | + >>> match = re.match(r'\d+', 'USERNAME@123') |
| 362 | + >>> print(match) |
| 363 | + None |
| 364 | + |
| 365 | + |
| 366 | + >>> match = re.search(r'\d+', '123@USERNAME') |
| 367 | + >>> print(match) |
| 368 | + <re.Match object; span=(0, 3), match='123'> |
| 369 | + |
| 370 | + >>> match = re.search(r'\d+', 'USERNAME@123') |
| 371 | + >>> print(match) |
| 372 | + <re.Match object; span=(9, 12), match='123'> |
| 373 | + |
| 374 | + |
| 375 | +.. tip:: |
| 376 | + |
| 377 | + تفاوت دو تابع ``match`` و ``search`` [`اسناد پایتون <https://docs.python.org/3/library/re.html#search-vs-match>`__]: |
| 378 | + |
| 379 | + هنگام استفاده از تابع ``match``، از همان ابتدای متن مورد نظر میبایست با الگو تطابق صورت پذیرد (حتی در متنهای چند سطری) ولی تابع ``search`` انجام انطباق را در هر جایی از متن دنبال میکند. |
| 380 | + |
| 381 | + هنگام استفاده از نشانه ``re.MULTILINE`` در تابع ``search``، کاراکتر ``^`` در الگو از معنای **ابتدای متن** به معنای **ابتدای هر سطر** تغییر میکند ولی از نظر تابع ``match`` وجود کاراکتر ``^`` در الگو همواره به معنی ابتدای متن میباشد (نه هر سطر):: |
| 382 | + |
| 383 | + >>> import re |
| 384 | + >>> string = 'Perl\nPython\nRuby' # 3 lines |
| 385 | + |
| 386 | + >>> match = re.search('^Perl', string) |
| 387 | + >>> print(match) |
| 388 | + <re.Match object; span=(0, 4), match='Perl'> |
| 389 | + |
| 390 | + >>> match = re.search('^Python', string) |
| 391 | + >>> print(match) |
| 392 | + None |
| 393 | + |
| 394 | + >>> match = re.search('^Python', string, re.MULTILINE) |
| 395 | + >>> print(match) |
| 396 | + <re.Match object; span=(5, 11), match='Python'> |
| 397 | + |
| 398 | + |
| 399 | + >>> match = re.match('^Perl', string) |
| 400 | + >>> print(match) |
| 401 | + <re.Match object; span=(0, 4), match='Perl'> |
| 402 | + |
| 403 | + >>> match = re.match('^Python', string, re.MULTILINE) |
| 404 | + >>> print(match) |
| 405 | + None |
| 406 | + |
| 407 | + |
| 408 | +اجازه بدهید یادآوری کنیم که دو نمونه کد زیر عملکردی معادل یکدیگر دارند:: |
| 409 | + |
| 410 | + |
| 411 | + >>> pattern = re.compile('Py...n') |
| 412 | + >>> match = pattern.match('Python is great') |
| 413 | + |
| 414 | +:: |
| 415 | + |
| 416 | + >>> match = re.match('Py...n', 'Python is great') |
| 417 | + |
| 418 | + |
| 419 | +تابع ``fullmatch`` |
| 420 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 421 | + |
| 422 | + |
| 423 | +``fullmatch(pattern, string, flags=0)`` |
| 424 | + |
| 425 | +این تابع (``fullmatch``) چنانچه تمام string با pattern انطباق داشته باشد یک شی ``Match`` و در غیر این صورت ``None`` برمیگرداند [`اسناد پایتون <https://docs.python.org/3/library/re.html#re.fullmatch>`__] - این تابع از **پایتون نسخه 3.4** به بعد در دسترس است:: |
| 426 | + |
| 427 | + >>> import re # Python >= 3.4 |
| 428 | + |
| 429 | + >>> match = re.fullmatch(r'\d+', '123@USERNAME') |
| 430 | + >>> print(match) |
| 431 | + None |
| 432 | + |
| 433 | + >>> match = re.fullmatch(r'\d+', '123') |
| 434 | + >>> print(match) |
| 435 | + <re.Match object; span=(0, 3), match='123'> |
| 436 | + |
| 437 | +**عملکرد نمونه کدهای زیر برابر هم هستند - به الگو و نام توابع توجه نمایید**:: |
| 438 | + |
| 439 | + >>> match = re.search(r'^\d+$', '123') |
| 440 | + >>> print(match) |
| 441 | + <re.Match object; span=(0, 3), match='123'> |
| 442 | + |
| 443 | + >>> match = re.match(r'\d+$', '123') |
| 444 | + >>> print(match) |
| 445 | + <re.Match object; span=(0, 3), match='123'> |
| 446 | + |
| 447 | + >>> match = re.fullmatch(r'\d+', '123') |
| 448 | + >>> print(match) |
| 449 | + <re.Match object; span=(0, 3), match='123'> |
| 450 | + |
| 451 | + |
| 452 | +همچنین باید یادآوری کنیم که دو نمونه کد زیر عملکردی معادل یکدیگر دارند:: |
| 453 | + |
| 454 | + |
| 455 | + >>> pattern = re.compile('Py...n') |
| 456 | + >>> match = pattern.fullmatch('Python') |
| 457 | + |
| 458 | +:: |
337 | 459 |
|
| 460 | + >>> match = re.fullmatch('Py...n', 'Python') |
338 | 461 |
|
339 | 462 |
|
340 | 463 |
|
|
0 commit comments