Avatar billede netro Nybegynder
30. maj 2006 - 11:55 Der er 16 kommentarer og
1 løsning

Match ALT-tekst i IMG-tag

Kan nogen af jer se, hvordan jeg får matchet alt-teksten her (inklusive det omgivende " eller ' hvis det er der)?

1) <IMG alt=xxx src="yyy">
2) <IMG alt=alt= src="yyy">
3) <IMG alt="x xx" src="yyy">
4) <IMG alt='xx"x' src="yyy">
5) <IMG alt="xx'x" src="yyy">
6) <IMG alt='src="' src="yyy">
7) <IMG alt='xxx">' src="yyy">

Der er selvfølgelig nogle regler.
Hvis alt-teksten indeholder ", bruges der ' omkring (4/6/7).
Hvis alt-teksten indeholder ' eller mellemrum, bruges der " omkring (3/5).
I alle andre tilfælde er der intet omkring.
Avatar billede morhan Novice
30. maj 2006 - 12:49 #1
hvilket sprog? i php med preg kan dette udtryk gøre det

$pattern = '/<img alt=(["\'])?(.*?)(?(1)\1|\s)/is';
Avatar billede netro Nybegynder
30. maj 2006 - 13:01 #2
C#
Avatar billede morhan Novice
30. maj 2006 - 13:21 #3
så bør den virke uden de helt store ændringer..

string pattern = "<img alt=([\"'])?(.*?)(?(1)\\1|[ \t\n])";

uden hverken ' " matcher den indtil mellemrum, tab eller newline
Avatar billede nielle Nybegynder
30. maj 2006 - 13:51 #4
Er du altid sikker på at "src" kommer efter "alt"? Eller kan dette forekomme:

<IMG src="yyy" alt="x xx">

?
Avatar billede netro Nybegynder
30. maj 2006 - 14:54 #5
nielle -> Det er også en regel, ja.

Den vil altid starte med <IMG alt= og den vil altid slutte med src="???">
Dog kan der jo så også stå: <IMG alt="<IMG alt=zzz"

morhan -> Jeg ser lige på det.
Avatar billede nielle Nybegynder
30. maj 2006 - 14:57 #6
I så fald er her et bud:

using System;
using System.Text.RegularExpressions;

namespace e712678
{
    class Program
    {
        static void Main(string[] args)
        {
            string tekst = @"1) <IMG alt=xxx src=""yyy""> \r\n2) <IMG alt=alt= src=""yyy"">\r\n3) <IMG alt=""x xx"" src=""yyy"">\r\n4) <IMG alt='xx""x' src=""yyy"">\r\n5) <IMG alt=""xx'x"" src=""yyy"">\r\n6) <IMG alt='src=""' src=""yyy"">\r\n7) <IMG alt='xxx"">' src=""yyy"">";

            Regex re1 = new Regex(@"(?<imgTag><img.+?alt=.+?src=.*?>)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match re1m = re1.Match(tekst);

            while (re1m.Success)
            {
                string imgTag = re1m.Groups["imgTag"].Value;
                Console.WriteLine(imgTag);

                Regex re2 = new Regex("alt=(?<delimiterChar>.)");
                Match re2m = re2.Match(imgTag);

                if (re2m.Success)
                {
                    string delimiterChar = re2m.Groups["delimiterChar"].Value;

                    Regex re3 = (delimiterChar == @"""" || delimiterChar == "'")
                        ? new Regex(string.Format("alt=(?<altAttribute>{0}.*?{0})", delimiterChar))
                        : new Regex(@"alt=(?<altAttribute>\S+)");
                    Match re3m = re3.Match(imgTag);

                    Console.WriteLine("ALT= {0}", re3m.Groups["altAttribute"].Value);
                }

                re1m = re1m.NextMatch();
            }
        }
    }
}
Avatar billede netro Nybegynder
31. maj 2006 - 18:41 #7
Tak for input begge to. Det ser ud til at virke. Jeg ved ikke helt, hvad det endelige resultat bliver. Men det skal nok blive godt. Smid svar.
Avatar billede nielle Nybegynder
01. juni 2006 - 17:29 #8
Et svar fra mig :^)

Jeg kunne faktisk gerne tænke mig at se en fungerende løsning på baseret på morhan's forslag hvis det er muligt. Selv kan jeg ikke rigtigt få den grejet.
Avatar billede netro Nybegynder
01. juni 2006 - 17:47 #9
Jeg har fået den implementeret, men den håndterer også en række andre ting nu. Her er et udklip, hvor hver alt-attribut gerne skulle blive udskrevet korrekt.

Regex Exp;
MatchCollection Coll;
string Str, TempStr;
int AltStart, AltEnd;
char Delimiter;

Str = "<img alt=xxx src="yyy">";

Exp = new Regex("<IMG [^a]*alt=([\"'])?(.*?)(?(1)\\1|[ \t\n])[^>]+>");
Coll = Exp.Matches(Str);
for (int i = Coll.Count - 1; i >= 0; i--)
{
      AltStart = Str.IndexOf("alt=", Coll[i].Index) + 4;
      Delimiter = Convert.ToChar(Str.Substring(AltStart, 1));
      if (Delimiter == '"' || Delimiter == '\'')
            AltEnd = Str.IndexOf(Delimiter, ++AltStart);
      else
            AltEnd = Str.IndexOf(" ", AltStart);

      Response.Write("alt=\"" + Str.Substring(AltStart, AltEnd - AltStart).Replace("\"", "&quot;") + "\"<br>");
}
Avatar billede nielle Nybegynder
01. juni 2006 - 18:58 #10
Hmm? Det virker nu ikke for mig:

using System;
using System.Text.RegularExpressions;

namespace e712678b
{
    class Program
    {
        static void Main(string[] args)
        {
            Regex Exp;
            MatchCollection Coll;
            string Str, TempStr;
            int AltStart, AltEnd;
            char Delimiter;

            Str = "<img alt=xxx src='yyy'>";

            Exp = new Regex("<IMG [^a]*alt=([\"'])?(.*?)(?(1)\\1|[ \t\n])[^>]+>");
            Coll = Exp.Matches(Str);
            for (int i = Coll.Count - 1; i >= 0; i--)
            {
                AltStart = Str.IndexOf("alt=", Coll[i].Index) + 4;
                Delimiter = Convert.ToChar(Str.Substring(AltStart, 1));
                if (Delimiter == '"' || Delimiter == '\'')
                    AltEnd = Str.IndexOf(Delimiter, ++AltStart);
                else
                    AltEnd = Str.IndexOf(" ", AltStart);

                Console.Write("alt=\"" + Str.Substring(AltStart, AltEnd - AltStart).Replace("\"", "&quot;") + "\"<br>");
            }
        }
    }
}

PS: Forresten kan du slette din TempStr - du bruger den slet ikke. :^)
Avatar billede morhan Novice
01. juni 2006 - 19:24 #11
Prøv img med Store bogstaver, eller lave den case insensitive
Avatar billede nielle Nybegynder
01. juni 2006 - 19:38 #12
Yep, det virker med en RegexOptions.IgnoreCase:

Exp = new Regex("<IMG [^a]*alt=([\"'])?(.*?)(?(1)\\1|[ \t\n])[^>]+>", RegexOptions.IgnoreCase);

Jeg gik egentlig bare ud fra at koden virkede som den var postet?
Avatar billede nielle Nybegynder
01. juni 2006 - 19:41 #13
Jeg afstår gerne fra point på denne her ... kan jo se at det er morhan's løsning som der er anvendt (med en enkelt væsentlig tilretning). :^)
Avatar billede netro Nybegynder
01. juni 2006 - 23:14 #14
nielle -> Ja, den kunne godt bruge en ignorecase og måske lidt andet for at gøre den mere generel anvendelig. Jeg har bare lavet den meget specifik, da jeg ved, hvad jeg kan forvente som input. Du skal i øvrigt nok få noget for din tid, selvom jeg endte med at tage udgangspunkt i morhans pattern.

morhan - > Kan du sige mig, hvordan man definerer, at et helt ord ikke må optræde i en streng? Altså ligesom man kan definere med en karakterklasse, at x, y og z ikke må optræde. [^xyz].
Avatar billede nielle Nybegynder
28. juni 2006 - 09:01 #15
Ud fra din formulering tror jeg at du måske har misforstået [^xyz] lidt. Den matcher et tegn som ikke er er x, y eller z, men dette betyder ikke at du kan bruge den til at tjekke for at et af disse tegn ikke optræder i en streng.

Match for at ordet "eksperten" ikke indgår i strengen:

            Regex re = new Regex("^((?!eksperten).)*$");
            if (re.Match(tekst).Success)
                Console.WriteLine("Ordet 'eksperten' indgår ikke i strengen");
            else
                Console.WriteLine("Der er fundet en ekspert!");

- men jeg vil nu mene at det er simplere at tjekke på om ordet findes og så handle på om det er en succesfuld match eller ej:

            re = new Regex("eksperten");
            if (!re.Match(tekst).Success)
                Console.WriteLine("Ordet 'eksperten' indgår ikke i strengen");
            else
                Console.WriteLine("Der er fundet en ekspert!");
Avatar billede netro Nybegynder
10. oktober 2006 - 03:11 #16
Så fik jeg nok formuleret mig forkert, for jeg ved godt, at det enten er x, y eller x og ikke hele strengen. Er det bare en parantes omkring, der skal til? Det synes jeg, at jeg havde prøvet.
Avatar billede nielle Nybegynder
10. oktober 2006 - 06:56 #17
Jeg ved ikke lige hvad du mener med "Er det bare en parantes omkring, der skal til?" Hvordan?

I den løsning jeg viser, som altså går på et helt ord, er det ikke bare en parentes der skal til. Det er en (?!...) som betyder "negative zero-width lookahead":

http://www.regular-expressions.info/lookaround.html
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
Kurser inden for grundlæggende programmering

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