Permalänk
Medlem

Regexp, färgsätta tabellrad

Mors

Ett konkret problem:

Jag försöker trolla fram ett php-skript som går igenom en existerande html-fil och färgsätter vissa tabellrader beroende på vad som står i dem.

Filen ser ut ungefär såhär:

<tr> <td>3249342</td> <td>*</td> <td></td> <td>description</td> <td>Linux</td> <td>1</td> <td>Planned</td> <td>0</td> <td>2007-04-05</td> <td>userid</td> <td>No</td> </tr> <tr> <td>3249343</td> <td>*</td> <td></td> <td>description</td> <td>Linux</td> <td>1</td> <td>Failed</td> <td>0</td> <td>2007-04-05</td> <td>userid</td> <td>No</td> </tr>

... i huvudsak, i alla fall, med en mängd dylika tabellrader.

Jag vill plocka ut rader beroende på det som står i sjunde cellen (i fallet ovan "Planned" eller "Failed") och sätta färg på raden därefter (bakgrundsfärg röd för "Failed") till exempel.

Nu .. behöver jag lite hjälp med ett läckert reguljärt uttryck som plockar ut hela den rad där "Planned" finns .. till att börja med.

Jag har lekt lite med regexp-testaren på http://regexlib.com/RETester.aspx och där kommit fram till att uttrycket
<tr>[^<]*[^/]*[^t]*[^r]*[^>]*Planned[^<]*[^t]*[^r]*[^>]*</tr>
matchar den tabellrad jag är ute efter.

Tyvärr funkar detta sämre om jag petar in det rätt av i PHPs preg_replace-funktion:
$contents = preg_replace("/^<tr>[^<]*[^/]*[^t]*[^r]*[^>]*Planned[^<]*[^t]*[^r]*[^>]*</tr>$/, "blaha", $contents);

Vad gör jag fel?

Visa signatur
Permalänk
Medlem

Tar preg_-funktionerna Perl-kompatibla regexps? I sådana fall måste du nog släng på ett s i slutet för att behandla din sträng som en rad.

I Perl matchar följande regexp den första raden:

/(<tr>.*?Planned.*?<\/tr>)/s

Edit: Det ska inte vara något mellanslag före ")/s". Jag vet inte varför forumet gör så.

Visa signatur

Bra, snabbt, billigt; välj två.

Ljud
PC → ODAC/O2 → Sennheiser HD650/Ultrasone PRO 900/...
PC → S.M.S.L SA300 → Bowers & Wilkins 607

Permalänk
Medlem

Provar ditt förslag, Phod, men då verkar den matcha hela tabellen i ett svep .. visst är det så att den försöker matcha ett så stort uttryck som möjligt? Jag är ute efter det motsatta .. ett så litet uttryck som möjligt. Dvs bara en tr ..

Visa signatur
Permalänk
Medlem

Frågetecknen efter .* ska göra att den försöker matcha så litet som möjligt. Jag lade till dem i en edit eftersom jag glömde dem först. Har du dem i din regexp?

Visa signatur

Bra, snabbt, billigt; välj två.

Ljud
PC → ODAC/O2 → Sennheiser HD650/Ultrasone PRO 900/...
PC → S.M.S.L SA300 → Bowers & Wilkins 607

Permalänk
Medlem

jag förstod inte riktigt vad du ville göra, men kan man inte
använda preg_replace och byta ut <td>Failed</td> mot <td class="failed">Failed</td>

Visa signatur

E6300 | Thermalright Ultra-120 eXtreme + Noctua 120mm 1200rpm | Gigabyte GA-965P-DS3 | 3GB Corsair XMS2-6400 CL5

Permalänk
Medlem

Alright, det blev en fullösning:

<?php $exploded = explode("<tr>", $contents); for($i = 1; $i < sizeof($exploded); $i++) { if (strstr($exploded[$i], 'Planned')) { $row_color = 'yellow'; } else if (strstr($exploded[$i], 'Passed')) { $row_color = 'green'; } else if (strstr($exploded[$i], 'Failed')) { $row_color = 'red'; } $exploded[$i] = '<tr style="background: ' . $row_color . '">' . $exploded[$i]; } foreach($exploded as $line) { echo $line; } ?>

Visa signatur
Permalänk

$parsed_str = preg_replace ('#<tr>(.*?)(<td>Failed</td>)(.*?)</tr>#is', '<tr class="failed">\1\2\3</tr>', $str);

Permalänk
Medlem

Vigg89: Din fungerar inte, den fungerar bara om det står <td>Failed</td> i alla rader, om inte så kommer den matcha felaktigt över flera rader / <tr>.

Här är en som jag hoppas fungerar, gjorde det i mina tester iaf.

<tr(>(?:(?!<tr>).)*?<td>(Failed|Planned)</td>(?:(?!<tr>).)*?</tr>)

Och för att ersätta kan man skriva så här:

preg_replace('/<tr(>(?:(?!<tr>).)*?<td>(Failed|Planned)<\/td>(?:(?!<tr>).)*?<\/tr>)/is', '<tr class="\2"\1', $str);

Permalänk
Citat:

Ursprungligen inskrivet av Rosenson
Vigg89: Din fungerar inte, den fungerar bara om det står <td>Failed</td> i alla rader, om inte så kommer den matcha felaktigt över flera rader / <tr>.

Här är en som jag hoppas fungerar, gjorde det i mina tester iaf.

<tr(>(?:(?!<tr>).)*?<td>(Failed|Planned)</td>(?:(?!<tr>).)*?</tr>)

Och för att ersätta kan man skriva så här:

preg_replace('/<tr(>(?:(?!<tr>).)*?<td>(Failed|Planned)<\/td>(?:(?!<tr>).)*?<\/tr>)/is', '<tr class="\2"\1', $str);

Hehe, det stämmer, tänkte inte helt på det