Difference between revisions of "SAP ABAP REGEX"
From SapWiki
| (11 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
| + | ==PCRE (Perl Compatible Regular Expressions)== | ||
| + | In modern ABAP (SAP NetWeaver 7.55 and higher), using the REPLACE FIRST OCCURRENCE OF REGEX statement triggers a syntax warning because POSIX-style regular expressions are obsolete. The ABAP compiler flags standard inline regex strings in these older statements as deprecated. | ||
| + | |||
| + | ===Ejemplo 1=== | ||
| + | <nowiki> | ||
| + | data: sub1 TYPE c LENGTH 80, | ||
| + | sub2 TYPE c LENGTH 80, | ||
| + | sub3 TYPE c LENGTH 80, | ||
| + | sub4 TYPE c LENGTH 80, | ||
| + | sub5 TYPE c LENGTH 80, | ||
| + | sub6 TYPE c LENGTH 80. | ||
| + | DATA lv_text TYPE string. | ||
| + | |||
| + | lv_text = sy-datlo. | ||
| + | |||
| + | " Create a PCRE-compliant regex object | ||
| + | DATA(lo_regex) = cl_abap_regex=>create_pcre( pattern = '(\d{4})(\d{2})(\d{2})' ). | ||
| + | |||
| + | REPLACE REGEX lo_regex IN lv_text WITH '$3/$2/$1'. | ||
| + | |||
| + | lv_text = sy-datlo. | ||
| + | |||
| + | FIND REGEX lo_regex IN lv_text SUBMATCHES sub1 sub2 sub3. | ||
| + | |||
| + | </nowiki> | ||
| + | ===Ejemplo REPLACE_REGEXPR en CDS view=== | ||
| + | <nowiki> | ||
| + | @AccessControl.authorizationCheck: #NOT_REQUIRED | ||
| + | define view entity demo_cds_sql_func_string_ve | ||
| + | as select from demo_expressions | ||
| + | { | ||
| + | length( char1 ) as r_length, | ||
| + | instr( char1, 'CD' ) as r_instr, | ||
| + | concat( char1, char2 ) as r_concat, | ||
| + | concat_with_space( char1, char2, 10 ) as r_concat_with_space, | ||
| + | left( char1, 3 ) as r_left, | ||
| + | lower( char1 ) as r_lower, | ||
| + | right( char2, 3 ) as r_right, | ||
| + | lpad( char1, 10, 'x' ) as r_lpad, | ||
| + | rpad( char2, 10, 'y' ) as r_rpad, | ||
| + | ltrim( char1, 'A' ) as r_ltrim, | ||
| + | rtrim( char1, 'E' ) as r_rtrim, | ||
| + | replace_regexpr( pcre => '\\Cg', | ||
| + | value => char2, | ||
| + | with => 'bb', | ||
| + | result_length => 4 ) as r_replace_regexpr, | ||
| + | replace( char2, 'ghi', 'XXX' ) as r_replace, | ||
| + | substring( char2, 2, 3 ) as r_substring, | ||
| + | upper( char2 ) as r_upper | ||
| + | } | ||
| + | </nowiki> | ||
| + | |||
== Ejemplos REGEX== | == Ejemplos REGEX== | ||
| Line 195: | Line 247: | ||
ENDFORM.</nowiki> | ENDFORM.</nowiki> | ||
| + | |||
| + | ===Encontrar primer espacio en blanco=== | ||
| + | En este ejemplo separamos el código de la transacción con su texto | ||
| + | VA01 Create Sales Order | ||
| + | ^(\S*)\s | ||
===Validar Hora=== | ===Validar Hora=== | ||
| Line 303: | Line 360: | ||
RS_SIC_REGEX_CHECK | RS_SIC_REGEX_CHECK | ||
DEMO_REGEX_TOY | DEMO_REGEX_TOY | ||
| + | DEMO_REGEX (con PCRE (Perl Compatible Regular Expressions) ) | ||
==Regular Expression Patterns== | ==Regular Expression Patterns== | ||
| − | + | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
{| class="wikitable" | {| class="wikitable" | ||
| Line 467: | Line 456: | ||
| +? || Reserved for later enhancements | | +? || Reserved for later enhancements | ||
|- | |- | ||
| − | | | | + | | <nowiki>|</nowiki> || Linking of two alternative expressions |
|- | |- | ||
| ( ) || Definition of subgroups with registration | | ( ) || Definition of subgroups with registration | ||
Latest revision as of 21:59, 6 September 2026
Contents
- 1 PCRE (Perl Compatible Regular Expressions)
- 2 Ejemplos REGEX
- 2.1 Ejemplo de Uso de regex en ABAP
- 2.2 validar rut (muy simple)
- 2.3 valida e-mail
- 2.4 validar Números
- 2.5 Elimina prefijo
- 2.6 convertir fecha (yyyymmdd->dd/mm/yyyy)
- 2.7 convertir TIMESTAMP
- 2.8 Convierte folio
- 2.9 usar REGEX como IF
- 2.10 obtener extensión de archivo
- 2.11 Encontrar primer espacio en blanco
- 2.12 Validar Hora
- 3 DEMOS
- 4 Regular Expression Patterns
PCRE (Perl Compatible Regular Expressions)
In modern ABAP (SAP NetWeaver 7.55 and higher), using the REPLACE FIRST OCCURRENCE OF REGEX statement triggers a syntax warning because POSIX-style regular expressions are obsolete. The ABAP compiler flags standard inline regex strings in these older statements as deprecated.
Ejemplo 1
data: sub1 TYPE c LENGTH 80,
sub2 TYPE c LENGTH 80,
sub3 TYPE c LENGTH 80,
sub4 TYPE c LENGTH 80,
sub5 TYPE c LENGTH 80,
sub6 TYPE c LENGTH 80.
DATA lv_text TYPE string.
lv_text = sy-datlo.
" Create a PCRE-compliant regex object
DATA(lo_regex) = cl_abap_regex=>create_pcre( pattern = '(\d{4})(\d{2})(\d{2})' ).
REPLACE REGEX lo_regex IN lv_text WITH '$3/$2/$1'.
lv_text = sy-datlo.
FIND REGEX lo_regex IN lv_text SUBMATCHES sub1 sub2 sub3.
Ejemplo REPLACE_REGEXPR en CDS view
@AccessControl.authorizationCheck: #NOT_REQUIRED
define view entity demo_cds_sql_func_string_ve
as select from demo_expressions
{
length( char1 ) as r_length,
instr( char1, 'CD' ) as r_instr,
concat( char1, char2 ) as r_concat,
concat_with_space( char1, char2, 10 ) as r_concat_with_space,
left( char1, 3 ) as r_left,
lower( char1 ) as r_lower,
right( char2, 3 ) as r_right,
lpad( char1, 10, 'x' ) as r_lpad,
rpad( char2, 10, 'y' ) as r_rpad,
ltrim( char1, 'A' ) as r_ltrim,
rtrim( char1, 'E' ) as r_rtrim,
replace_regexpr( pcre => '\\Cg',
value => char2,
with => 'bb',
result_length => 4 ) as r_replace_regexpr,
replace( char2, 'ghi', 'XXX' ) as r_replace,
substring( char2, 2, 3 ) as r_substring,
upper( char2 ) as r_upper
}
Ejemplos REGEX
Ejemplo de Uso de regex en ABAP
DATA: lt_match_result TYPE match_result_tab.
data: l_regex type string,
l_string type string.
data: l_matches TYPE i.
l_regex = '^[^<>()\[\]\\,;:\s@"`]+@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$'.
l_string = 'pablo.tapia@sapwiki.cl'.
FIND ALL OCCURRENCES OF REGEX l_regex IN l_string
IN CHARACTER MODE RESPECTING CASE
MATCH COUNT l_matches RESULTS lt_match_result.
if l_matches le 0.
message i000(0k) with 'E-mail no valido' display like 'E'.
return.
endif.
validar rut (muy simple)
FIND REGEX '[0-9]{1,8}-([0-9]|K)' IN l_strng.
valida e-mail
^[^<>()\[\]\\,;:\s@"`]+@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$
validar Números
validar número
1.1111 correcto
-1.1111 correcto
1.11111- correcto
1111 correcto
^[-?0-9]+([.])?([0-9]+)?-?$
números de 2 enteros y 7 decimales
1.1234567 correcto
11.1234560 correcto
^[0-9]{1,2}\.([0-9]{7})+$
con signo izquierda
-1.1234567 correcto
1.1234567 correcto
^-?[0-9]{1,2}\.([0-9]{7})+$
con signo derecha o izquierda
^-?[0-9]{1,2}\.([0-9]{7})+-?$
validar número entero
^[0-9]+$
numero NNN.NN
valido
111.1
11.11
1
^\d{1,3}(\.\d{1,2})?$
numero entero con máximo de 13 caracteres
valido
1234567890111
111
1
^\d{1,13}$
MODULE verificar_folio INPUT.
DATA l_string TYPE string.
DATA l_folio(7) TYPE n.
IF zfi_datoscajas-folio IS NOT INITIAL.
MOVE zfi_datoscajas-folio TO l_string.
CONDENSE l_string.
FIND REGEX '[^\d]' IN l_string IN CHARACTER MODE RESPECTING CASE.
IF sy-subrc = 0.
MESSAGE e000(0k) WITH 'Folio deber contener solo números'.
ELSE.
MOVE l_string TO l_folio.
MOVE l_folio TO zfi_datoscajas-folio.
ENDIF.
ENDIF.
ENDMODULE.
Elimina prefijo
* NC00000009 -> 00000009 *saca prefijos de XBLNR data l_xblnr type string. l_xblnr = vbrk-xblnr. REPLACE all OCCURRENCES OF REGEX '[[:alpha:]]' IN l_xblnr with ''. if sy-subrc = 0. .... endif.
ejemplo 2
REPLACE all OCCURRENCES OF REGEX '[^\d]' in l_xblnr WITH ''.
convertir fecha (yyyymmdd->dd/mm/yyyy)
data l_fecha(10).
l_fecha = sy-datum.
replace FIRST OCCURRENCE OF REGEX '(\d{4})(\d{2})(\d{2})'
in l_fecha WITH '$3/$2/$1'.
write:/ l_fecha.
convertir TIMESTAMP
DD.MM.YYYY HORA => YYYY-MM-DD HORA Ejemplo: 03.10.2025 14:55:44 => 2025-10-03 14:55:44
FORM get_timestamp CHANGING ev_timestamp TYPE string.
DATA: lv_short_timestamp TYPE timestamp.
DATA lv_timestamp(30).
GET TIME STAMP FIELD lv_short_timestamp.
WRITE lv_short_timestamp TO lv_timestamp TIME ZONE sy-zonlo.
REPLACE FIRST OCCURRENCE OF REGEX '(\d{2})\.(\d{2})\.(\d{4})\s(.*)'
IN lv_timestamp WITH '$3-$2-$1 $4'.
MOVE lv_timestamp TO ev_timestamp.
ENDFORM.
Convierte folio
* Folio1: PRmmaaRppnnnnnn
* Folio2: 0208020 + aa + mm + nnnnnn
* Ejemplo: PR0720R007188233 se convierte en 02080202007188233
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM conv_folio USING p_xblnr TYPE bsis-xblnr
CHANGING p_folio TYPE ze_folio.
DATA l_string TYPE string.
CLEAR p_folio.
l_string = p_xblnr.
REPLACE FIRST OCCURRENCE OF REGEX '(.{2})(.{2})(.{2})(.{1})(.{1})(.{2})(.{6})'
IN l_string WITH '0208020$3$2$7'.
IF sy-subrc = 0.
p_folio = l_string.
ENDIF.
ENDFORM.
usar REGEX como IF
ejemplo para verificar por clase de entrega data l_lfart type string. l_lfart = likp-lfart. find REGEX 'Y101|Y100|Y102' in l_lfart. if sy-subrc = 0. write:/ 'continue'. else. write:/ 'Exit'. endif.
obtener extensión de archivo
FORM get_extension USING iv_file TYPE string
CHANGING ev_ex TYPE string.
DATA: lt_match_result TYPE match_result_tab.
DATA: lv_regex TYPE string,
lv_string TYPE string.
DATA: lv_matches TYPE i.
DATA: lv_file(250).
lv_regex = '\.([^.]+)$'.
lv_string = iv_file.
lv_file = iv_file.
FIND ALL OCCURRENCES OF REGEX lv_regex IN lv_string
IN CHARACTER MODE RESPECTING CASE
MATCH COUNT lv_matches RESULTS lt_match_result.
IF lv_matches > 0.
DESCRIBE TABLE lt_match_result LINES DATA(lv_lines).
READ TABLE lt_match_result INTO DATA(ls_result) INDEX lv_lines. "get the last occurrence
ls_result-offset = ls_result-offset + 1.
ev_ex = lv_file+ls_result-offset.
ENDIF.
ENDFORM.
Encontrar primer espacio en blanco
En este ejemplo separamos el código de la transacción con su texto
VA01 Create Sales Order ^(\S*)\s
Validar Hora
Para validar una hora en formato HH:MM (24 horas) donde los ceros a la izquierda sean obligatorios (ej. 09:05), utiliza la siguiente expresión regular: [1]
^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$
Explicación del patrón:
- ^ e $: Indican el inicio y el final de la cadena, asegurando que no haya caracteres adicionales. [1, 2]
- (0[0-9]|1[0-9]|2[0-3]): Valida la sección de la hora.
- 0[0-9]: Permite horas desde 00 hasta 09.
- 1[0-9]: Permite horas desde 10 hasta 19.
- 2[0-3]: Permite horas desde 20 hasta 23. [1, 2]
- :: Separa las horas de los minutos.
- [0-5][0-9]: Valida los minutos del 00 al 59. [1]
opciones:
- Horas con cero inicial opcional (ej. 9:05):
^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$
- Formato de 12 horas con AM/PM (ej. 09:05 PM):
^(0?[1-9]|1[0-2]):[0-5][0-9] ?[AaPp][Mm]$
- Máximo horas 99:59
^([0-9]{1,2}):([0-5][0-9])$
Ejemplos en EXITS
FUNCTION conversion_exit_zhora_input.
*"----------------------------------------------------------------------
*"*"Interfase local
*" IMPORTING
*" VALUE(INPUT)
*" EXPORTING
*" VALUE(OUTPUT)
*"----------------------------------------------------------------------
*01:30 => 1,5 hrs
DATA: lt_match_result TYPE match_result_tab.
DATA: lv_regex TYPE string,
lv_string TYPE string.
DATA: lv_matches TYPE i.
DATA: lv_hora_texto TYPE char5,
lv_horas TYPE i,
lv_minutos TYPE i,
lv_decimal TYPE p LENGTH 8 DECIMALS 2.
lv_string = input.
lv_regex = '^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$'.
FIND ALL OCCURRENCES OF REGEX lv_regex IN lv_string
IN CHARACTER MODE RESPECTING CASE
MATCH COUNT lv_matches RESULTS lt_match_result.
IF lv_matches LE 0.
MESSAGE e000(0k) WITH 'Formato horas inválido, debe ser en HH:MM'.
ENDIF.
lv_hora_texto = input.
* 1. Separamos las horas y los minutos
SPLIT lv_hora_texto AT ':' INTO DATA(lv_hr_str) DATA(lv_min_str).
lv_horas = lv_hr_str.
lv_minutos = lv_min_str.
* 2. Aplicamos la fórmula matemática
lv_decimal = lv_horas + ( lv_minutos / 60 ).
output = lv_decimal.
ENDFUNCTION.
FUNCTION CONVERSION_EXIT_ZHORA_OUTPUT.
*"----------------------------------------------------------------------
*"*"Interfase local
*" IMPORTING
*" VALUE(INPUT)
*" EXPORTING
*" VALUE(OUTPUT)
*"----------------------------------------------------------------------
*1,5 horas => 01:30
DATA: lv_decimal TYPE p DECIMALS 2 VALUE '8.75', " Ejemplo: 8.75 horas
lv_minutos_totales TYPE i,
lv_horas TYPE i,
lv_minutos TYPE i,
lv_resultado TYPE string.
lv_decimal = input.
" 1. Convertir horas decimales a minutos totales
lv_minutos_totales = lv_decimal * 60.
" 2. Calcular horas (división entera por 60)
lv_horas = lv_minutos_totales DIV 60.
" 3. Calcular minutos restantes
lv_minutos = lv_minutos_totales MOD 60.
" 4. Formatear el resultado a HH:MM con ceros a la izquierda
lv_resultado = |{ lv_horas WIDTH = 2 ALIGN = RIGHT PAD = '0' }:{ lv_minutos WIDTH = 2 ALIGN = RIGHT PAD = '0' }|.
CONDENSE lv_resultado.
output = lv_resultado. " Salida esperada: 08:45
ENDFUNCTION.
DEMOS
RS_SIC_REGEX_CHECK DEMO_REGEX_TOY DEMO_REGEX (con PCRE (Perl Compatible Regular Expressions) )
Regular Expression Patterns
| Special character | Meaning |
|---|---|
| . | Placeholder for any single character |
| \C | Placeholder for any single character |
| \d | Placeholder for any single digit |
| \D | Placeholder for any character other than a digit |
| \l | Placeholder for any lower-case letter |
| \L | Placeholder for any character other than a lower-case letter |
| \s | Placeholder for a blank character |
| \S | Placeholder for any character other than a blank character |
| \u | Placeholder for any upper-case letter |
| \U | Placeholder for any character other than an upper-case letter |
| \w | Placeholder for any alphanumeric character including _ |
| \W | Placeholder for any non-alphanumeric character except for _ |
| [ ] | Definition of a value set for single characters |
| [^ ] | Negation of a value set for single characters |
| [ - ] | Definition of a range in a value set for single characters |
| [ [:alnum:] ] | Description of all alphanumeric characters in a value set |
| [ [:alpha:] ] | Description of all letters in a value set |
| [ [:blank:] ] | Description for blank characters and horizontal tabulators in a value set |
| [ [:cntrl:] ] | Description of all control characters in a value set |
| [ [:digit:] ] | Description of all digits in a value set |
| [ [:graph:] ] | Description of all graphic special characters in a value set |
| [ [:lower:] ] | Description of all lower-case letters in a value set |
| [ [:print:] ] | Description of all displayable characters in a value set |
| [ [:punct:] ] | Description of all punctuation characters in a value set |
| [ [:space:] ] | Description of all blank characters, tabulators, and carriage feeds in a value set |
| [ [:unicode:] ] | Description of all Unicode characters in a value set with a code larger than 255 |
| [ [:upper:] ] | Description of all upper-case letters in a value set |
| [ [:word:] ] | Description of all alphanumeric characters in a value set, including _ |
| [ [:xdigit:] ] | Description of all hexadecimal digits in a value set |
| \a \f \n \r \t \v | Diverse platform-specific control characters |
| [..] | Reserved for later enhancements |
| [==] | Reserved for later enhancements |
| Special character | Meaning |
|---|---|
| {n} | Concatenation of n single characters |
| {n,m} | Concatenation of at least n and a maximum of m single characters |
| {n,m}? | Reserved for later enhancements |
| ? | One or no single characters |
| * | Concatenation of any number of single characters including 'no characters' |
| *? | Reserved for later enhancements |
| + | Concatenation of any number of single characters excluding 'no characters' |
| +? | Reserved for later enhancements |
| | | Linking of two alternative expressions |
| ( ) | Definition of subgroups with registration |
| (?: ) | Definition of subgroups without registration |
| \1, \2, \3 ... | Placeholder for the register of subgroups |
| \Q ... \E | Definition of a string of literal characters |
| (? ... ) | Reserved for later enhancements |
| Special character | Meaning |
|---|---|
| ^ | Anchor character for the start of a line |
| \A | Anchor character for the start of a character string |
| $ | Anchor character for the end of a line |
| \Z | Anchor character for the end of a character string |
| \< | Start of a word |
| \> | End of a word |
| \b | Start or end of a word |
| \B | Space between characters within a word |
| (?= ) | Preview condition |
| (?! ) | Negated preview condition |
| Special character | Meaning |
|---|---|
| $0, $& | Placeholder for the whole found location |
| $1, $2, $3... | Placeholder for the register of subgroups |
| $` | Placeholder for the text before the found location |
ejemplos
^ start line $ end line ^\w+$ matches one or more word characters (same as [a-zA-Z0-9_]+). Ex. TRUE: 33737733aaaaaa_aaaaaa FALSE: 33737733aaa+aaa_aaaaaa ^[0-9]+$ or ^\d+$ Full Numeric Strings \S+, one or more non-whitespaces