This commit is contained in:
danrega
2024-12-02 09:49:17 +01:00
parent 23d6c43d52
commit 91d7033370
15 changed files with 458 additions and 148 deletions

View File

@@ -13,7 +13,7 @@
- [Capturing Groups, Replacements and Backreferences](#capturing-groups-replacements-and-backreferences)
- [Lookarounds](#lookarounds)
- [Case Conversions in Replacement Patterns](#case-conversions-in-replacement-patterns)
- [Option Settings and Control Verbs](#option-settings-and-control-verbs)
- [Setting Options and Control Verbs](#setting-options-and-control-verbs)
- [Callouts](#callouts)
- [Coniditional Patterns](#coniditional-patterns)
- [ABAP Statements Using Regular Expressions](#abap-statements-using-regular-expressions)
@@ -30,7 +30,7 @@ Regular expressions
- Offer a powerful way to perform complex searching, replacing, and matching
- Can be used in ABAP in the following contexts (with a focus on PCRE):
- `FIND` and `REPLACE` statements (with the `PCRE` addition)
- Built-in functions in ABAP with the `pcre` parameter, such as `find`, `find_end`, `count`, `match`, `replace`, `substring_from`, `substring_after`, `substring_before`, `substring_to`
- Built-in functions in ABAP with the `pcre` parameter, such as `find`, `find_end`, `count`, `match`, `matches`, `replace`, `contains`, `substring_from`, `substring_after`, `substring_before`, `substring_to`
- Built-in functions in ABAP SQL and CDS (e.g. `like_regexpr`, `locate_regexpr`, `locate_regexpr_after`, `occurrences_regexpr`, `replace_regexpr`, `substring_regexpr` in ABAP SQL)
- `CL_ABAP_REGEX` and `CL_ABAP_MATCHER` classes (note that you can also use objects of `CL_ABAP_REGEX` in `FIND` and `REPLACE` statements)
- Are supported in ABAP with the following syntaxes:
@@ -48,17 +48,17 @@ Regular expressions
> **💡 Note**<br>
> - You can perform complex searches using regular expressions. For simple pattern-based searches, refer to comparison operators (`CP`, `NP`) in the [String Processing](07_String_Processing.md) cheat sheets.
> - The cheat sheet and examples focus on PCRE regular expressions. For other syntax types, find more information and links in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABENREGEX_SYNTAX.html).
> - If you have access to a system supporting [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm), you can check out the `demo_regex_toy` program for experimenting with regular expressions in ABAP.
> - In a system supporting [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm), you can check out the `demo_regex_toy` program for experimenting with regular expressions in ABAP.
<p align="right"><a href="#top">⬆️ back to top</a></p>
## Excursion: Common Regular Expressions
> **💡 Note**<br>
> - The sections below provide an overview of common PCRE expressions with examples. This is not a comprehensive overview; only selected expressions are included.
> - The sections below provide an overview of common PCRE expressions with examples. This is not a comprehensive overview; only selected regular expressions are included.
> - For a complete guide to PCRE syntax, refer to the [official documentation](https://perldoc.perl.org/perlre). Note that ABAP-specific restrictions or modifications may apply to the standard syntax.
> - The code snippets use `replace` functions to show the effects of PCRE regular expressions. Many examples use the `occ = 0` parameter to replace all occurrences.
> - When using regular expressions, note that exceptions such as of type `cx_sy_invalid_regex` (invalid regex) or `cx_sy_regex_too_complex` (too complex regex) can occur.
> - The code snippets use `replace` functions to show the effects of PCRE regular expressions. Many examples use the `occ` parameter with the assignment `occ = 0` to replace all occurrences.
> - When using regular expressions, note that exceptions such as of type `cx_sy_invalid_regex` or `cx_sy_regex_too_complex` can occur.
### Characters and Character Types
@@ -138,28 +138,28 @@ DATA string_esc_chars TYPE string.
"Special characters
"a#b#c#d#e#f#g
string_chars_types = replace( val = `a[b]c\d/e^f.g` pcre = `\[|\]|\\|\/|\^|\.` with = `#` occ = 0 ).
string_esc_chars = replace( val = `a[b]c\d/e^f.g` pcre = `\[|\]|\\|\/|\^|\.` with = `#` occ = 0 ).
"Line feeds
"a#b#c
string_chars_types = replace( val = |a\nb\nc| pcre = `\n` with = `#` occ = 0 ).
string_esc_chars = replace( val = |a\nb\nc| pcre = `\n` with = `#` occ = 0 ).
"Line feed negation
"String template representation of the result: |#\n#\n#|
string_chars_types = replace( val = |a\nb\nc| pcre = `\N` with = `#` occ = 0 ).
string_esc_chars = replace( val = |a\nb\nc| pcre = `\N` with = `#` occ = 0 ).
"Tabs
"a#b#c
string_chars_types = replace( val = |a\tb\tc| pcre = `\t` with = `#` occ = 0 ).
string_esc_chars = replace( val = |a\tb\tc| pcre = `\t` with = `#` occ = 0 ).
"Carriage return
"d#e#f
string_chars_types = replace( val = |d\re\rf| pcre = `\r` with = `#` occ = 0 ).
string_esc_chars = replace( val = |d\re\rf| pcre = `\r` with = `#` occ = 0 ).
"Characters with hex code
"The example string includes a non-breaking space.
"#x#
string_chars_types = replace(
string_esc_chars = replace(
val = |#{ cl_abap_conv_codepage=>create_in( codepage = `UTF-16BE` )->convert( source = CONV xstring( `00A0` ) ) }#|
pcre = `\x{00A0}` with = `x` occ = 0 ).
@@ -167,22 +167,22 @@ string_chars_types = replace(
"As above, the example string includes a non-breaking space.
"The PCRE syntax uses the control verb (*UTF) to enable UTF mode.
"#y#
string_chars_types = replace(
string_esc_chars = replace(
val = |#{ cl_abap_conv_codepage=>create_in( codepage = `UTF-16BE` )->convert( source = CONV xstring( `00A0` ) ) }#|
pcre = `(*UTF)\N{U+00A0}` with = `y` occ = 0 ).
"Characters with a specified Unicode character property
"H# ABAP
string_chars_types = replace( val = `Hello ABAP` pcre = `\p{Ll}+` with = `#` occ = 0 ).
string_esc_chars = replace( val = `Hello ABAP` pcre = `\p{Ll}+` with = `#` occ = 0 ).
"#ello #
string_chars_types = replace( val = `Hello ABAP` pcre = `\p{Lu}+` with = `#` occ = 0 ).
string_esc_chars = replace( val = `Hello ABAP` pcre = `\p{Lu}+` with = `#` occ = 0 ).
"#ello#
string_chars_types = replace( val = `Hello ABAP` pcre = `\P{Ll}+` with = `#` occ = 0 ).
string_esc_chars = replace( val = `Hello ABAP` pcre = `\P{Ll}+` with = `#` occ = 0 ).
"H#ABAP
string_chars_types = replace( val = `Hello ABAP` pcre = `\P{Lu}+` with = `#` occ = 0 ).
string_esc_chars = replace( val = `Hello ABAP` pcre = `\P{Lu}+` with = `#` occ = 0 ).
```
<p align="right"><a href="#top">⬆️ back to top</a></p>
@@ -300,9 +300,9 @@ string_char_sets_ranges = replace( val = `ABCDabcd123456` pcre = `[^A-Ca-c1-4]`
| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
|---|---|---|---|---|---|
| `\A` | Start of a subject | `\A.` | abc def | <ins>**a**</ins>bc def | abc <ins>**d**</ins>ef |
| `^` | Start of a subject (particularly relevant in multi line mode) | `^.` | See above and more details in the option settion section | | |
| `^` | Start of a subject (particularly relevant in multi-line mode) | `^.` | See above and more details in the option setting section | | |
| `\Z` | End of a subject | `.\Z` | abc def | abc de<ins>**f**</ins> | <ins>**a**</ins>bc def |
| `$` | End of a subject (particularly relevant in multi line mode) | `.$` | See above and more details in the option settion section | | |
| `$` | End of a subject (particularly relevant in multi-line mode) | `.$` | See above and more details in the option setting section | | |
| `\b` | Start or end of word | 1. `\ba.` <br>2. `\Dd\b` <br>3. `\b.d\b` | abcd a12d ed | 1. <ins>**ab**</ins>cd <ins>**a1**</ins>2d ed <br>2. ab<ins>**cd**</ins> a12d <ins>**ed**</ins> <br> 3. abcd a12d <ins>**ed**</ins> | 1. ab<ins>**cd**</ins> a1<ins>**2d**</ins> ed <br> 2. abcd a1<ins>**2d**</ins> ed <br> 3. <ins>**abcd**</ins> <ins>**a12d**</ins> ed |
| `\B` | Negation of `\b`, not at the start or end of words | `\Be\B` | see an elefant | s<ins>**e**</ins>e an el<ins>**e**</ins>fant | s<ins>**ee**</ins> an <ins>**e**</ins>lefant |
| `\K` | Resets the starting point of a match, i.e. findings are excluded from the final match | `a.\Kc` | abcd | ab<ins>**c**</ins>d | <ins>**abc**</ins>d |
@@ -318,13 +318,13 @@ DATA string_anchors_pos TYPE string.
"#abc def
string_anchors_pos = replace( val = `abc def` pcre = `\A` with = `#` occ = 0 ).
"Start of subject, syntax ^; find more information below regarding multi line mode
"Start of subject, syntax ^; find more information below regarding multi-line mode
"#abc
"#def
"#ghi
string_anchors_pos = replace( val = |abc\ndef\nghi| pcre = `(?m)^` with = `#` occ = 0 ).
"The following examples uses ^ without enabling the multi line mode
"The following examples uses ^ without enabling the multi-line mode
"#abc
"def
"ghi
@@ -335,7 +335,7 @@ string_anchors_pos = replace( val = |abc\ndef\nghi| pcre = `^` with = `#` occ =
string_anchors_pos = replace( val = `abc def` pcre = `\Z` with = `#` occ = 0 ).
"End of subject, syntax $
"The example uses multi line mode
"The example uses multi-line mode
"abc#
"def#
"ghi#
@@ -369,7 +369,7 @@ string_anchors_pos = replace( val = `abcd` pcre = `a.\Kc` with = `#` occ = 0 ).
| `(...)` | Capturing group to group parts of patterns together | `b(a\|u)t` | bit bat but bet | bat, but | bit, bet |
| `(?<name>...)`, `(?'name'...)` | Named capturing group | `(?<x>..)(?'y'..)` | abcd | `$x` refers to *ab*, `$y` to *cd* <br> The reference can also be made using curly brackets: `${x}`, `${y}` | `$x` refers to *cd*, `$y` to *ab* |
| `$id`, `${id}` | Represents the substitute for a capturing group, `id` stands for a number or name of a capturing group | `(..)(..)` | abcd | `$1` refers to *ab*, `$2` to *cd* <br> `$0` refers to the content of the whole match <br> As above, the reference can also be made using curly brackets: `${0}`, `${1}`, `${2}` | `$1` refers to *cd*, `$2` to *ab* |
| `(?:...)` | Creates a group but it is not captured | `(?:ab)(ap)` | abap | It matches *abap*, but in a replacements and when referring to the subgroup `$1`, it refers to *ap*. | ab |
| `(?:...)` | Creates a group but it is not captured | `(?:ab)(ap)` | abap | It matches *abap*, but in a replacement and when referring to the subgroup `$1`, it refers to *ap*. | ab |
| `\1` | Backreference, refers to a previous capturing group; 1 represents the number of the group index (the group index starts with 1); more back reference syntax options are possible such as the specification of named groups | `(a.)(\w*)\1` | abcdefabghij | <ins>**abcdefab**</ins>ghij <br>Note: Capturing group 1 holds `ab` in the example. The second capturing group captures all word characters until `ab` is found. | <ins>**ab**</ins>cdefabghij |
Examples:
@@ -501,7 +501,6 @@ string_case_conv = replace( val = `HIJKLMNO` pcre = `K(.*)` with = `K\l$1` ).
string_case_conv = replace( val = `HIJKLMNO` pcre = `K(.*)` with = `K\L$1` ).
"\E syntax
"abcDEfg
string_case_conv = replace( val = `abcdefg` pcre = `c(..)(..)` with = `c\U$1\E$2` ).
@@ -512,7 +511,7 @@ string_case_conv = replace( val = `abcdefg` pcre = `c(..)(..)` with = `c\U$1$2`
<p align="right"><a href="#top">⬆️ back to top</a></p>
### Option Settings and Control Verbs
### Setting Options and Control Verbs
There are various [setting options](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/abenregex_pcre_syntax_specials.html) for specifying PCRE syntax. The following examples demonstrate a selection:
@@ -549,14 +548,14 @@ string_opt_set = replace( val = |\n\n| pcre = `(?s).` with = `#` occ = 0 ).
"----------- Examples for the start of subjects -----------
"Multi line mode not enabled
"Multi-line mode not enabled
"Result:
"#bc
"def
"ghi
string_opt_set = replace( val = |abc\ndef\nghi| pcre = `^.` with = `#` occ = 0 ).
"Multi line mode enabled
"Multi-line mode enabled
"Result:
"#bc
"#ef
@@ -595,7 +594,7 @@ string_opt_set = replace( val = |abc\ndef\nghi| pcre = `(?m).\Z` with = `#` occ
- The extended mode is the default for ABAP statements and built-in functions, but you can disable it in the regex pattern with `(?-x)`. The `create_pcre` method of the `CL_ABAP_REGEX` class includes an `extended` parameter for this purpose.
- To handle whitespaces in regular expressions, escape it with `\ `, match it using `\s`, or enable extended mode with `(?-x)`.
The following code snippet shows extended mode enabled by default and then explicitly disabled in a PCRE regular expression.
The following code snippet shows the extended mode enabled by default and then explicitly disabled in a PCRE regular expression.
```abap
@@ -622,7 +621,7 @@ some_string = replace( val = `abc def` pcre = `abc\ def` with = `#` ).
"are ignored.
some_string = replace( val = `abc def` pcre = `abc\ def` with = `#` ).
"Disabling the extended mode, so whitespaces are not ignored
"Disabling the extended mode so that whitespaces are not ignored
"Result: #
some_string = replace( val = `abc def` pcre = `(?-x)abc def` with = `#` ).
```
@@ -650,7 +649,7 @@ ctrl_verb_string = replace(
"Line breaks
"The results are demonstrated using string templates.
"In the examples, the multi line mode is enabled in addition.
"In the examples, the multi-line mode is enabled in addition.
"|_abc\ndef\r_ghi\r_\njkl|
ctrl_verb_string = replace( val = |abc\ndef\rghi\r\njkl|
@@ -741,7 +740,7 @@ CLASS zcl_some_class IMPLEMENTATION.
APPEND |start_match_off: { start_match_off }| TO callout_tab.
TRY.
APPEND |Content of match: { subject+capture_last_off(capture_last_len) }| TO callout_tab.
APPEND |Content of submatch: { subject+capture_last_off(capture_last_len) }| TO callout_tab.
CATCH cx_sy_range_out_of_bounds.
ENDTRY.
APPEND |This callout was called at { ts }| TO callout_tab.
@@ -869,7 +868,7 @@ FIND PCRE `(.*)\son\s(.*)` IN str IGNORING CASE RESULTS DATA(e).
* 21 25
"----- MATCH OFFSET/LENGTH additions -----
"The following examples find the last occurence of a comma and the following content.
"The following examples find the last occurrence of a comma and the following content.
"\K denotes that the comma is excluded from the result. Using the offset and length
"values, the part of the string is extracted. The examples underscore that you can
"achieve the same thing differently with different PCRE syntax patterns (which also
@@ -914,12 +913,12 @@ FIND FIRST OCCURRENCE OF PCRE `\bt.` IN TABLE itab
DATA(url) = `https://help.sap.com/docs/abap-cloud/abap-concepts/controlled-sap-luw/`.
DATA url_parts TYPE string_table.
FIND ALL OCCURRENCES OF PCRE `(?<=/)([^/]+)(?=/)` IN url RESULTS DATA(res).
FIND ALL OCCURRENCES OF PCRE `(?<=\/)([^\/]+)(?=\/)` IN url RESULTS DATA(res).
"Details on the regular expression:
"- Positive lookbehind (?<=/) that determines that the content is preceded by `/`
"- Positive lookahead (?=/) that determines that the content is followed by `/
"- ([^/]+) in between determines that any sequence of characters that are not `/` are matched
"- Positive lookbehind (?<=\/) that determines that the content is preceded by `/`
"- Positive lookahead (?=\/) that determines that the content is followed by `/
"- ([^\/]+) in between determines that any sequence of characters that are not `/` are matched
"- The match is put in parentheses to store the submatch
LOOP AT res INTO DATA(finding).
@@ -1098,6 +1097,20 @@ DATA(substring_from) = substring_from( val = text pcre = `\s` occ = 2 ).
"... up to a matching regular expression including the match
"'Lorem ipsum '
DATA(substring_to) = substring_to( val = text pcre = `\s` occ = 2 ).
"---------------- Predicate functions: contains, matches ----------------
"The built-in functions 'contains' returns a truth value. In the following
"examples, the truth value is demonstrated using the xsdbool function.
"X
DATA(contains) = xsdbool( contains( val = `abc def` pcre = `\s` ) ).
"The built-in functions 'matches' compares a search range of the textual argument
"with a regular expression.
"X
DATA(matches) = xsdbool( matches( val = `jon.doe@email.com`
pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ) ).
```
<p align="right"><a href="#top">⬆️ back to top</a></p>
@@ -1200,8 +1213,8 @@ DATA(str) = `a1 # B2 ? cd . E3`.
"using cl_abap_regex
"Example pattern: Any-non digit followed by a digit
DATA(regex_1) = cl_abap_regex=>create_pcre( pattern = `\D\d`
ignore_case = abap_true ).
DATA(regex) = cl_abap_regex=>create_pcre( pattern = `\D\d`
ignore_case = abap_true ).
"----------- Creating matchers -----------
@@ -1216,7 +1229,7 @@ DATA(regex_1) = cl_abap_regex=>create_pcre( pattern = `\D\d`
"with the 'table' parameter and more.
"Creating a matcher using the create_matcher method of the cl_abap_regex class
DATA(matcher_1) = regex_1->create_matcher( text = str ).
DATA(matcher_1) = regex->create_matcher( text = str ).
"Creating a matcher in one go using method chaining
DATA(matcher_2) = cl_abap_regex=>create_pcre( pattern = `\D\d`
ignore_case = abap_true
@@ -1231,7 +1244,7 @@ DATA(matcher_3) = cl_abap_matcher=>create_pcre( pattern = `\D\d`
"--- Finding all occurrences using the find_all method ---
"In the example, result has the type match_result_tab containing the findings.
DATA(result_1) = matcher_1->find_all( ).
DATA(result_fa1) = matcher_1->find_all( ).
*LINE OFFSET LENGTH SUBMATCHES
*0 0 2 OFFSET LENGTH
@@ -1240,24 +1253,24 @@ DATA(result_1) = matcher_1->find_all( ).
*
*0 15 2 OFFSET LENGTH
DATA(result_2) = matcher_2->find_all( ).
ASSERT result_2 = result_1.
DATA(result_fa2) = matcher_2->find_all( ).
ASSERT result_fa2 = result_fa1.
"Getting the result in one go using method chaining with cl_abap_matcher
DATA(result_3) = cl_abap_matcher=>create_pcre( pattern = `\D\d`
DATA(result_fa3) = cl_abap_matcher=>create_pcre( pattern = `\D\d`
text = str
ignore_case = abap_true
)->find_all( ).
ASSERT result_3 = result_1.
ASSERT result_fa3 = result_fa1.
"--- Example with subgroups ---
"--- Example with submatches ---
str = `XabcdXXefgXXhXXijklmnXX`.
DATA(result_4) = cl_abap_matcher=>create_pcre( pattern = `X(.*?)X`
text = str
ignore_case = abap_true
)->find_all( ).
DATA(result_fa4) = cl_abap_matcher=>create_pcre( pattern = `X(.*?)X`
text = str
ignore_case = abap_true
)->find_all( ).
*LINE OFFSET LENGTH SUBMATCHES
*0 0 6 OFFSET LENGTH
@@ -1271,20 +1284,20 @@ DATA(result_4) = cl_abap_matcher=>create_pcre( pattern = `X(.*?)X`
"--- Replacing all occurrences using the 'replace_all' method ---
DATA(matcher_4) = cl_abap_regex=>create_pcre( pattern = `X(.*?)X`
)->create_matcher( text = str ).
DATA(matcher_repl_1) = cl_abap_regex=>create_pcre( pattern = `X(.*?)X`
)->create_matcher( text = str ).
"4
DATA(repl_count_1) = matcher_4->replace_all( newtext = `#` ).
DATA(repl_count_1) = matcher_repl_1->replace_all( newtext = `#$1#` ).
"####X
DATA(repl_result_1) = matcher_4->text.
"#abcd##efg##h##ijklmn#X
DATA(repl_result_1) = matcher_repl_1->text.
"Using cl_abap_matcher
DATA(matcher_5) = cl_abap_matcher=>create_pcre( pattern = `X(.*?)X`
text = str ).
DATA(repl_count_2) = matcher_5->replace_all( newtext = `#` ).
DATA(repl_result_3) = matcher_5->text.
DATA(matcher_repl_2) = cl_abap_matcher=>create_pcre( pattern = `X(.*?)X`
text = str ).
DATA(repl_count_2) = matcher_repl_2->replace_all( newtext = `#$1#` ).
DATA(repl_result_2) = matcher_repl_2->text.
"---- Sequential processing of the regular expression ---
"---- using the find_next method ------------------------
@@ -1293,18 +1306,18 @@ DATA(repl_result_3) = matcher_5->text.
str = `a1bc2def3ghij45klm67opqr8stuvwx90yz`.
DATA(matcher_6) = cl_abap_matcher=>create_pcre( pattern = `\d(\D.)`
text = str ).
DATA(matcher_fn) = cl_abap_matcher=>create_pcre( pattern = `\d(\D.)`
text = str ).
DATA strtab TYPE string_table.
WHILE matcher_6->find_next( ) = abap_true.
WHILE matcher_fn->find_next( ) = abap_true.
APPEND |---- Finding { sy-index } -----| TO strtab.
"Type match_result
DATA(match_result) = matcher_6->get_match( ).
DATA(match_result) = matcher_fn->get_match( ).
DATA(offset) = matcher_6->get_offset( ).
DATA(length) = matcher_6->get_length( ).
DATA(offset) = matcher_fn->get_offset( ).
DATA(length) = matcher_fn->get_length( ).
DATA(matched_content) = str+offset(length).
APPEND |Match offset: { offset }| TO strtab.
@@ -1312,14 +1325,14 @@ WHILE matcher_6->find_next( ) = abap_true.
APPEND |Match content: { matched_content }| TO strtab.
"Type match_result
DATA(subgroup) = matcher_6->get_match( )-submatches.
DATA(subgroup) = matcher_fn->get_match( )-submatches.
LOOP AT subgroup INTO DATA(wa).
DATA(sub_tabix) = sy-tabix.
DATA(submatch_line) = wa.
DATA(submatch_offset) = wa-offset.
DATA(submatch_length) = wa-length.
DATA(submatch) = matcher_6->get_submatch( sub_tabix ).
DATA(submatch) = matcher_fn->get_submatch( sub_tabix ).
APPEND |Submatch { sub_tabix } offset: { submatch_offset }| TO strtab.
APPEND |Submatch { sub_tabix } length: { submatch_length }| TO strtab.
APPEND |Submatch { sub_tabix } content: { submatch }| TO strtab.
@@ -1330,16 +1343,16 @@ ENDWHILE.
"---- Using an object of type cl_abap_regex in ABAP ---
"---- statements with the REGEX addition --------------
DATA(result_5) = cl_abap_matcher=>create_pcre( pattern = `\d(\D.)`
text = str
)->find_all( ).
DATA(result_6) = cl_abap_regex=>create_pcre( pattern = `\d(\D.)`
DATA(result_find_all_1) = cl_abap_matcher=>create_pcre( pattern = `\d(\D.)`
text = str
)->find_all( ).
DATA(result_find_all_2) = cl_abap_regex=>create_pcre( pattern = `\d(\D.)`
)->create_matcher( text = str
)->find_all( ).
DATA(regex_2) = cl_abap_regex=>create_pcre( pattern = `\d(\D.)` ).
DATA(reg_expr) = cl_abap_regex=>create_pcre( pattern = `\d(\D.)` ).
FIND ALL OCCURRENCES OF REGEX regex_2 IN str RESULTS DATA(result_7).
FIND ALL OCCURRENCES OF REGEX reg_expr IN str RESULTS DATA(result_find_all_3).
*LINE OFFSET LENGTH SUBMATCHES
*0 1 3 OFFSET LENGTH
@@ -1357,19 +1370,77 @@ FIND ALL OCCURRENCES OF REGEX regex_2 IN str RESULTS DATA(result_7).
*0 32 3 OFFSET LENGTH
* 33 2
ASSERT result_7 = result_5.
ASSERT result_7 = result_6.
ASSERT result_find_all_3 = result_find_all_1.
ASSERT result_find_all_3 = result_find_all_2.
"Note that the REGEX addition is obsolete when using (POSIX) syntax patterns
"A syntax warning is displayed for the following example.
"FIND ALL OCCURRENCES OF REGEX `\d(\D.)` IN str RESULTS DATA(result_8).
"The syntax warning can be suppressed using a pragma
FIND ALL OCCURRENCES OF REGEX `\d(\D.)` IN str RESULTS DATA(result_9) ##REGEX_POSIX.
FIND ALL OCCURRENCES OF REGEX `\d(\D.)` IN str RESULTS DATA(result_find_all_4) ##REGEX_POSIX.
"Using PCRE instead
FIND ALL OCCURRENCES OF PCRE `\d(\D.)` IN str RESULTS DATA(result_10).
ASSERT result_10 = result_7.
FIND ALL OCCURRENCES OF PCRE `\d(\D.)` IN str RESULTS DATA(result_find_all_5).
ASSERT result_find_all_5 = result_find_all_3.
"---------------- Exploring more parameters of the create_pcre method ----------------
"See the class documentation for more parameters and information.
"--- enable_multiline parameter ---
str = |abc\ndef\nghi\njkl|.
DATA(matcher_no_ml) = cl_abap_matcher=>create_pcre( pattern = `^`
text = str ).
"1
DATA(repl_count_no_ml) = matcher_no_ml->replace_all( newtext = `#` ).
"|#abc\ndef\nghi\njkl|
DATA(repl_result_no_ml) = matcher_no_ml->text.
DATA(matcher_w_ml) = cl_abap_matcher=>create_pcre( pattern = `^`
text = str
enable_multiline = abap_true ).
"4
DATA(repl_count_w_ml) = matcher_w_ml->replace_all( newtext = `#` ).
"|#abc\n#def\n#ghi\n#jkl|
DATA(repl_result_w_ml) = matcher_w_ml->text.
"--- table/ignore_case parameters ---
data(str_table) = VALUE string_table( ( `abZdez` ) ( `zZfghZ` ) ( `ijkZZz` ) ( `zzzzZ` ) ).
DATA(matcher_tab) = cl_abap_matcher=>create_pcre( pattern = `z+`
table = str_table
ignore_case = abap_true ).
"6
DATA(repl_count_tab) = matcher_tab->replace_all( newtext = `#` ).
"ab#de# / #fgh# / ijk# / #
DATA(repl_result_tab) = matcher_tab->table.
"--- extended parameter ---
str = `abc def`.
DATA(matcher_w_extended) = cl_abap_matcher=>create_pcre( pattern = `abc def`
text = str ).
"No replacement in the following example as the extended mode is
"enabled by default.
"0
DATA(repl_count_w_extended) = matcher_w_extended->replace_all( newtext = `#` ).
"abc def
DATA(repl_result_w_extended) = matcher_w_extended->text.
"Disabling the extended mode so that whitespaces are not ignored
DATA(matcher_not_extended) = cl_abap_matcher=>create_pcre( pattern = `abc def`
text = str
extended = abap_false ).
"1
DATA(repl_count_not_extended) = matcher_not_extended->replace_all( newtext = `#` ).
"#
DATA(repl_result_not_extended) = matcher_not_extended->text.
```
<p align="right"><a href="#top">⬆️ back to top</a></p>