Question

J'ai cette chaîne de caractères contenant une grande partie de html et suis en train d'extraire le lien à partir href="..." partie de la chaîne.Href pourrait être dans l'une des formes suivantes:

<a href="..." />
<a class="..." href="..." />

Je n'ai pas vraiment avoir un problème avec la regex, mais pour une raison quelconque, quand j'utilise le code suivant:

        String innerHTML = getHTML(); 
  Pattern p = Pattern.compile("href=\"(.*)\"", Pattern.DOTALL);
  Matcher m = p.matcher(innerHTML);
  if (m.find()) {
   // Get all groups for this match
   for (int i=0; i<=m.groupCount(); i++) {
    String groupStr = m.group(i);
    System.out.println(groupStr);

   }
  }

Quelqu'un peut me dire quel est le problème avec mon code?J'ai fait ce truc en php, mais en Java, je suis en quelque sorte de faire quelque chose de mal...Ce qui se passe, c'est qu'il imprime à l'ensemble de la chaîne html à chaque fois que j'essaie d'imprimer...

EDIT:Juste pour que tout le monde sait quel genre de string, je m'occupe de:

<a class="Wrap" href="item.php?id=43241"><input type="button">
    <span class="chevron"></span>
  </a>
  <div class="menu"></div>

Chaque fois que je lance le code, il imprime l'ensemble de la chaîne...C'est le problème...

Et sur l'utilisation de jTidy...Je suis sur elle, mais il serait intéressant de savoir ce qui n'allait pas dans ce cas...

Était-ce utile?

La solution

.* 

Ceci est une opération gourmande qui aura un caractère, y compris les guillemets.

Essayez quelque chose comme:

"href=\"([^\"]*)\""

Autres conseils

Il y a deux problèmes avec le code que vous avez posté:

Tout d'abord la .* dans votre expression régulière est gourmand. Cela lui fera correspondre tous les caractères jusqu'à ce que le dernier caractère " qui peut être trouvé. Vous pouvez faire ce match soit non gourmand en changeant cela .*?.

En second lieu, pour ramasser tous les matches, vous devez garder itérer avec Matcher.find plutôt que de chercher des groupes. Les groupes vous donnent accès à chaque section du parenthésée regex. Vous cependant, cherchez chaque fois correspond à toute l'expression régulière.

Mettre ces ensemble, vous donne le code suivant qui devrait faire ce que vous avez besoin:

Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.DOTALL);
Matcher m = p.matcher(innerHTML);

while (m.find()) 
{
    System.out.println(m.group(1));
}

Regex est grande, mais pas le bon outil à cet effet particulier. Normalement, vous voulez utiliser un analyseur stackbased pour cela. Jetez un oeil à l'API Java analyseur HTML est comme JTidy .

Utiliser un parseur.Quelque chose comme:

    EditorKit kit = new HTMLEditorKit();
    HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument();
    doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
    kit.read(reader, doc, 0);

    HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);

    while (it.isValid())
    {
        SimpleAttributeSet s = (SimpleAttributeSet)it.getAttributes();
        String href = (String)s.getAttribute(HTML.Attribute.HREF);
        System.out.println( href );
        it.next();
    }

Ou utiliser le ParserCallback:

import java.io.*;
import java.net.*;
import javax.swing.text.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;

public class ParserCallbackText extends HTMLEditorKit.ParserCallback
{
    public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos)
    {
        if (tag.equals(HTML.Tag.A))
        {
            String href = (String)a.getAttribute(HTML.Attribute.HREF);
            System.out.println(href);
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        Reader reader = getReader(args[0]);
        ParserCallbackText parser = new ParserCallbackText();
        new ParserDelegator().parse(reader, parser, true);
    }

    static Reader getReader(String uri)
        throws IOException
    {
        // Retrieve from Internet.
        if (uri.startsWith("http:"))
        {
            URLConnection conn = new URL(uri).openConnection();
            return new InputStreamReader(conn.getInputStream());
        }
        // Retrieve from file.
        else
        {
            return new FileReader(uri);
        }
    }
}

Le Lecteur pourrait être un StringReader.

Une autre façon simple et fiable pour le faire est en utilisant Jsoup

Document doc = Jsoup.connect("http://example.com/").get();
Elements links = doc.select("a[href]");
for (Element link : links){
  System.out.println(link.attr("abs:href"));
}

vous pouvez utiliser une parser html. JTidy par exemple, vous donne un modèle DOM du html, vous pouvez partir Wich extraire tous les éléments « a » et lire leur attribut "href"

"href=\"(.*?)\"" devrait également fonctionner, mais je pense que la réponse de Kugel fonctionnera plus rapidement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top