-2

I've been looking for answer but i didn't find.

I want to remove classes b-c and e from string which contains html.

$tmp = '<div class="a b-c d e">b-c</div>';
$tmp2 = '<div class="a b-c d">b-c</div>';
$tmp3 = '<div class="a e b-c d">b-c</div>';
$tmp4 = '<div class="a d e">b-c</div>';

I tried somethinkg like this

preg_replace('#class="(.*?)(b-c|e)(.*?)"#si', 'class="\\1\\3"', $a)

but it doesn't work in all cases(not for $tmp and $tmp2).

After regex $tmp,$tmp2, $tmp3, $tmp4 should

<div class="a d">b-c</div>

I would like this regex will remove all classes in all cases regardless of how many classes there are and regardless of order Can anyony help me? I'm not good in regex :/

Sylwek
  • 856
  • 1
  • 9
  • 24
  • you meant it works for some classes and doesnt work for some? – MohitC Oct 16 '15 at 10:39
  • I meant that there can be a lot of other classes and i want to remove only some of them – Sylwek Oct 16 '15 at 10:40
  • For what classes your current regex work? – MohitC Oct 16 '15 at 10:44
  • 5
    Regex are the wrong tool for this. You should have a look at DOM parsing: http://php.net/manual/en/refs.xml.php / http://simplehtmldom.sourceforge.net/ – Reeno Oct 16 '15 at 10:44
  • https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – Bogdan Burym Oct 16 '15 at 10:45
  • I know i can use DOM parser, but i would like to do this with one regex expresion - if that is possible. – Sylwek Oct 16 '15 at 10:51
  • @Sylwek It's possible with regex. but you probably will never find a 100% bulletproof solution with regex – Reeno Oct 16 '15 at 11:35
  • Why do you want to do this with regex if you aren't good at regex? (I don't mean to sound judgmental; I'm not very good at regex either.) It doesn't seem like a good idea to include code you don't really understand just to save a few lines vs. using a DOM parser. – Don't Panic Oct 16 '15 at 14:51

2 Answers2

2

If you want to use regex (but is always better to use a DOM parser), you can reach your goal in this way:

<?php

$tmp = '<div class="a b-c d e">b-c</div>';
$tmp2 = '<div class="a b-c d">b-c</div>';
$tmp3 = '<div class="a e b-c d">b-c</div>';
$tmp4 = '<div class="a d e">b-c</div>';

function remove($tmp) {
    return preg_replace_callback('/class="([^"]+)"/', function($m) {
    if(strpos($m[1], "b-c") !== false) {
        $m[0] = preg_replace("/\s*b-c\s*/",' ',$m[0],1);
    }
    if(strpos($m[1],"e") !== false) {
        $m[0] = preg_replace("/\s*e\s*/",' ',$m[0], 1);
    }
    return $m[0];
    }, $tmp);
}

echo remove($tmp), "\n", remove($tmp2), "\n", remove($tmp3), "\n" , remove($tmp4);

Outputs:

<div class="a d ">b-c</div>
<div class="a d">b-c</div>
<div class="a d">b-c</div>
<div class="a d ">b-c</div>

Not perfect (there's a trailing space) but it works well (spaces are allowed in class attribute).

I hope it helps

nessuno
  • 26,493
  • 5
  • 83
  • 74
0

You can try the following code using str_replace

str_replace(" b-c ", " ", $tmp); // This will replace b-c if it is not the first or last class
str_replace("b-c ", " ", $tmp); // This will replace b-c if it is the first class
str_replace(" b-c", " ", $tmp); // This will replace b-c if it is the last class
str_replace('"b-c"', '""', $tmp); // This will replace b-c if it is the only class and the quotes for the class HTML property are double quotes

This code won't delete the b-c that is in <div>b-c</div> because it searches for b-c with spaces before or after

FastFarm
  • 409
  • 1
  • 6
  • 21
  • and what is b-c is last class of div? and what for class e he wants to remove too – MohitC Oct 16 '15 at 10:46
  • if b-c is the last class he would use the last line of code I used. This checks if there is a space before `b-c` which would be `
    b-c
    ` I will add comments to the lines explaining what each one is for
    – FastFarm Oct 16 '15 at 10:49