2012 Sep 09 1:47 PM
Hi,
I have an HTML file and I want to replace/edit some tags inside it.
Sor example, I have:
<span style="font-weight: bold; font-family: Arial;">some_text</span>
I want to receive the following result:
<span style="font-family: Arial;"><strong>some_text</strong></span>
In other words, I want to replace some part/property of SPAN-tag by surrounding the text inside of SPAN-tag by suitable tag.
The problem is that desired property can be at the beginning of SPAN or at the end.
And not every SPAN tag does contain such property at all.
As I can guess, the best way to do this is RegEx, but I don't really know how can I surround text with HTML tag in regullar expression.
Thanks.
2012 Oct 08 4:39 AM
Hi, I solved my issue.
Detailed explanation of the subject published in separate post on my blog.
«Regular expressions in ABAP. Approach to HTML processing with regex» —
Hi,
I have an HTML file and I want to replace/edit some tags inside it.
Sor example, I have:
<span style="font-weight: bold; font-family: Arial;">some_text</span>
I want to receive the following result:
<span style="font-family: Arial;"><strong>some_text</strong></span>
In other words, I want to replace some part/property of SPAN-tag by surrounding the text inside of SPAN-tag by suitable tag.
The problem is that desired property can be at the beginning of SPAN or at the end.
And not every SPAN tag does contain such property at all.
As I can guess, the best way to do this is RegEx, but I don't really know how can I surround text with HTML tag in regullar expression.
Thanks.
2012 Sep 11 11:00 PM
2012 Sep 12 3:46 AM
Hi Mike,
If we could assume that the font-weight attribute is always first
then we could use regex
(<span style=")(font-weight[^;]*;)([^;]*;)*(">)([^<]*)(</span>)
with replacement
$1$3$4<strong>$5</strong>$6
this works in regex toy..
To deal with the unkown order of the tags, you would need to have 2 scenarios in the regex.
(font-weight[^;]*;)([^;]*;)*|([^;]*;)*(font-weight[^;]*)
ie where weight comes first or last.
Regex Toy does not give me enough space to test this, but the I can guess the replacment would not work because the order would be different each time.
So you could call the replace 2 times - once as above, once as
(<span style=")([^;]*;)*(font-weight[^;]*;)(">)([^<]*)(</span>)
with
$1$2$4<strong>$5</strong>$6
If you want to use one regex search string, then you could use the object-based regex matching though CL_ABAP_MATCHER, and manually work out which submatch needs to be removed, and then rebuild the section based on the other submatches along with the strong tags....
Anyway, hope this helps you along with finding a solution
2012 Sep 12 7:20 AM
Hi, Phillip
In my case, each span-tag can has a different content and order of properties, e.g. in some SPAN tag we can see only font-weight, in other there are both font-weight and text-decoration or even 3 of them — font-style, font-weight and text-decoration.
So we have to take in account all of these combinations.
Can you clarify, please, what is the meaning of each part of the string ([^;]*;)*(font-weight[^;]*)?
Why we're using «*» between «[^;]*;)» and «(font-weight[^;]*)». What exactly does [^;] and *;.
Thanks.
2012 Sep 12 9:05 AM
Ok, I'll try to explain....
[^;] will match a single character that is not a ";".
[^;]* will match any string of characters that are not ";"
[^;]*; will match any string of characters that are not ";", but that do eventually end in a ";".
The brackets are for subgroup registration, which means we can use that match later in replacements.
So, the string here "([^;]*;)" is saying: find and remember the string of characters that ends in a ";".
This should find the "font-family: Arial;" string.
Problem is: it will also match the "font-style: bold;" string, but we want to deal with that case separately so we can put it into a different subgroup.
Which is why I have the "(font-style[^;]*;), so we can isolate that exact attribute.
But I'll stop there because a good rule to follow with regular expressions is:
don't use one that you don't understand or can't explain.
Or: it's a bad idea to blindy use code you get from a forum.
You probably should do some trial and error testing in program demo_regex_toy.
If you look up the standard help on keyword FIND, you can navigate to an explanation of the Regex syntax. There are also plenty of internet tutorials on regex (for UNIX or Java) in general. The ABAP regex syntax is slightly different to the UNIX/Java syntax, but you can get the idea from those tutorials.
Cheers,
Phil
2012 Sep 12 9:23 AM
Actually, the problem interested me and I wrote a little program (I can't help it ).
REPORT zregextest01.
*----------------------------------------------------------------------*
* CLASS lcl_regex_test DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_regex_test DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
pattern TYPE string,
write_matches
IMPORTING
text_template TYPE string.
DATA: text_template TYPE string,
pattern TYPE string.
ENDCLASS. "lcl_regex_test DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_regex_test IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_regex_test IMPLEMENTATION.
METHOD constructor.
me->pattern = pattern.
ENDMETHOD. "constructor
METHOD write_matches.
DATA: matcher TYPE REF TO cl_abap_matcher,
matches TYPE match_result_tab,
match TYPE match_result,
submatch TYPE submatch_result,
output_text type string.
matcher = cl_abap_matcher=>create(
pattern = pattern
text = text_template ).
matches = matcher->find_all( ).
IF matches IS INITIAL.
WRITE: / 'No matches'.
ENDIF.
LOOP AT matches INTO match.
WRITE: / 'Full match:', text_template+match-offset(match-length).
WRITE: / 'Submatches:'.
LOOP AT match-submatches INTO submatch.
CHECK submatch-offset >= 0.
output_text = | { sy-tabix } { text_template+submatch-offset(submatch-length) }|.
WRITE: / output_text.
ENDLOOP.
ENDLOOP.
ENDMETHOD. "write_matches
ENDCLASS. "lcl_regex_test IMPLEMENTATION
INITIALIZATION.
DATA: test_matcher TYPE REF TO lcl_regex_test,
text_template TYPE string,
pattern TYPE string.
pattern = `(<span style=")` &&
`(?:` &&
`(font-weight: ([^;]*);)([^;]*;)*(">)` &&
`|` &&
`([^;]*;)+( font-weight: ([^;]*);)(">)` &&
`|` &&
`([^;]*;)+( font-weight: ([^;]*);)([^;]*;)+(">)` &&
`)` &&
`([^<]*)` &&
`(</span>)`.
CREATE OBJECT test_matcher
EXPORTING
pattern = pattern.
* case where the font-weight is first
text_template = `<span style="font-weight: bold; font-family: Arial;">some_text</span>`.
test_matcher->write_matches( text_template ).
* case where the font-weight is last
text_template = `<span style="font-family: Arial; font-weight: bold;">some_text</span>`.
test_matcher->write_matches( text_template ).
* case where the font-weight is in between
text_template = `<span style="font-family: Arial; font-weight: bold; text-decoration: none;">some_text</span>`.
test_matcher->write_matches( text_template ).
2012 Oct 08 4:39 AM
Hi, I solved my issue.
Detailed explanation of the subject published in separate post on my blog.
«Regular expressions in ABAP. Approach to HTML processing with regex» —
| User | Count |
|---|---|
| 3 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |