Avatar billede driis Nybegynder
03. oktober 2004 - 12:23 Der er 18 kommentarer og
1 løsning

Regular expression : find alle table rows

Jeg mangler en regular expression, der kan hive alle table rows ud af en html tabel. Jeg er selv kommet frem til denne:
Regex regRows = new Regex("<tr.*>.*</tr>",RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline );

... men beklageligvis finder den kun den første række, selvom der er rigtig mange rækker i input strengen. Jeg bruger følgende:

Match m = regRows.Match(content);
while ( m.Success )
{
  // do stuff
  // .....

  m = m.NextMatch();
}
Avatar billede driis Nybegynder
03. oktober 2004 - 12:24 #1
Og spørgsmålet er selvfølgelig: Er der fejl i min Regex, i måden jeg bruger den på, eller gør jeg noget helt andet forkert ?
Avatar billede arne_v Ekspert
03. oktober 2004 - 12:35 #2
using System;
using System.Text.RegularExpressions;

class MainClass
{
    public static void Main(string[] args)
    {
        test("<table border>\n" +
            "<tr>\n" +
            "<td>1</td>\n" +
            "<td>a</td>\n" +
            "</tr>\n" +
            "<tr>\n" +
            "<td>2</td>\n" +
            "<td>bb</td>\n" +
            "</tr>\n" +
            "<tr>\n" +
            "<td>3</td>\n" +
            "<td>ccc</td>\n" +
            "</tr>\n" +
            "</table>\n");
    }
    private static void test(string s)
    {
        MatchCollection res = Regex.Matches(s,"<tr[^>]*>[\\S\\s]*?</tr>");
        for(int i = 0; i < res.Count; i++) {
            Console.WriteLine("match " + i + " = " + res[i].Groups[0]);
        }
    }
}
Avatar billede arne_v Ekspert
03. oktober 2004 - 12:35 #3
Output:

match 0 = <tr>
<td>1</td>
<td>a</td>
</tr>
match 1 = <tr>
<td>2</td>
<td>bb</td>
</tr>
match 2 = <tr>
<td>3</td>
<td>ccc</td>
</tr>
Avatar billede snepnet Nybegynder
03. oktober 2004 - 12:36 #4
Du kan benyttes RegEx.Matches istedet... den skulle finde alle dem der er
Avatar billede snepnet Nybegynder
03. oktober 2004 - 12:36 #5
hehe... der var jeg lidt sent ude :o)
Avatar billede arne_v Ekspert
03. oktober 2004 - 12:36 #6
Men der er mange måder at gøre det på.
Avatar billede snepnet Nybegynder
03. oktober 2004 - 12:39 #7
arne hvorfor vil du ikke bruge sådan en

Matcthes matches = Regex.Matches(...);
foreach(Match match in matches)
{
    // match.Value kan der kigges på her
}
Avatar billede arne_v Ekspert
03. oktober 2004 - 12:41 #8
Om det er en for løkke eller en foreach før jo ikke den store forskel.

Jeg brugte Groups fordi det i virkeligheden er sjældent at det er Groups[0] man vil
have fat i, men at man vil have noget indeni.
Avatar billede snepnet Nybegynder
03. oktober 2004 - 12:43 #9
ok - jeg synes bare koden er dejlig læsbar på den anden måde, og på dit match ligger .Groups også klar til brug.
Avatar billede snepnet Nybegynder
03. oktober 2004 - 12:44 #10
men som du siger har det jo ikke den store betydning.
Avatar billede arne_v Ekspert
03. oktober 2004 - 13:05 #11
Jeg ved ikke om:

    private static void test(string s)
    {
        MatchCollection res = Regex.Matches(s,"<tr[^>]*>[\\S\\s]*?</tr>");
        foreach(Match r in res) {
            Console.WriteLine("match = " + r.Value);
        }
    }

er specielt mere læsbart.
Avatar billede snepnet Nybegynder
03. oktober 2004 - 13:08 #12
nu skrev jeg jo også bare at jeg synes koden er mere læsbar - andre behøver bestemt ikke mene det samme ;o)
mvh
Avatar billede driis Nybegynder
03. oktober 2004 - 14:27 #13
arne_v, dit forslag fungerer, du må gerne lægge et svar.

Men kan du forklare, hvorfor min første regex ikke virker ?
Avatar billede arne_v Ekspert
03. oktober 2004 - 14:35 #14
Jeg er ikke sikker.

Men 2 mulige forklaringer:

<tr.*> => .* som greedy kan inkludere >
.* => det er ikke sikkert at . dækker linie skift
Avatar billede arne_v Ekspert
03. oktober 2004 - 14:36 #15
Derfor erstattede jeg <tr.*> med <tr[^>]*> og .* med [\\S\\s]*?
Avatar billede arne_v Ekspert
03. oktober 2004 - 14:36 #16
svar
Avatar billede arne_v Ekspert
03. oktober 2004 - 14:37 #17
NB: Dine RegexOptions kan du sagtens putte på i min variant også
Avatar billede driis Nybegynder
03. oktober 2004 - 14:48 #18
Det lyder fornuftigt.

"<tr.*> => .* som greedy kan inkludere >"
Hvordan kontrollerer man om en regex matcher greedy eller non-greedy ?
Avatar billede arne_v Ekspert
03. oktober 2004 - 14:49 #19
[\\S\\s]* er greedy
[\\S\\s]*? er reluctant
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester