Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Replace SPAN-property tag by HTML tag via RegEx

mikeb
Contributor
0 Likes
2,581

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.

1 ACCEPTED SOLUTION
Read only

mikeb
Contributor
0 Likes
1,762

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» —

http://scn.sap.com/community/abap/blog/2012/10/08/a-regular-expression-regex-approach-to-html-proces...

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.

6 REPLIES 6
Read only

mikeb
Contributor
0 Likes
1,762

Does any have idea how to deal with this issue?

Read only

0 Likes
1,762

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

Read only

0 Likes
1,762

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.

Read only

0 Likes
1,762

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

Read only

0 Likes
1,762

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 ).

Read only

mikeb
Contributor
0 Likes
1,763

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» —

http://scn.sap.com/community/abap/blog/2012/10/08/a-regular-expression-regex-approach-to-html-proces...