Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Ramael

Procurar palavra em site

Recommended Posts

De boas pessoal?

Estou eu cá de volta com mais uma de minhas dúvidas, vamos lá.

 

Estou, como título diz, tentando encontrar umas palavras dentro de um site, estou usando uma funçãozinha assim:

	<?php
		$url = file_get_contents('ENDEREÇO DE UM SITE');
		$buscar   = '@';
		while(($numero_ocorrencias = strpos($url, $buscar, $numero_ocorrencias+1)) != 0)
			{
			echo $numero_ocorrencias.' '.'<br />';
			}
	?>

Ele vai buscar todas as incidências do @ na tal página, mas ele só me mostra a posição. Eu queria que ele me mostrasse toda a palavra, no caso e-mail, que está junto com o arroba.

 

Já tentei procurar isso no Google de diversas formas, mas só encontrei referências ao strpos. Alguém conhece algo a respeito, se não uma solução, pelo menos a forma correta de se procurar isso.

 

Obrigado pessoal.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você terá de usar expressões regulares. A função preg_match_all vai ajudar nisso.

 

Há uma ferramenta chamada PHPCrawl, pra fazer crawler em PHP. Nunca usei, mas talvez lhe seja útil :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá pessoal.

Como disse antes, eu consegui e o código que fiz ficou assim:

		$url = file_get_contents('teste.html');
		$pattern = "/mailto:(.*)\" /";
		$subject   = $url;
		// $matches = array();
		$resultado = preg_match_all($pattern, $subject, $matches);
		foreach ($matches [1] as $key =>$value) {
			echo $key." - ".$value." <br>";
		}

Mas agora quero pegar os links dessa página, mas sem pegar os e-mails. Então fiz uma regra assim na minha ER:

 

$pattern = "/href=\"[^mailto:](.*)\"/";
Que na minha cabeça significa, que será mostrado tudo que estiver entre o href=" e a outra ", menos o que contiver mailto:
ele até pega exatamente isso, mas o problema é que a primeira letra de cada resultado está sendo omitida. :huh:
Assim:
0 - age1.html
1 - age2.html
2 - age3.html
3 - age4.html
4 - age5.html
Quando na verdade era pra ser Page.
Não entendi o porquê disso estar acontecendo.
Alguém?
Obrigado pessoal.
T+
Ramael
ps.: Uma dúvida que não tem muita importância: Tem como a contagem começar do 1, mas sem omitir o resultado todo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema está aqui:

 

[^mailto:]

 

Isso é uma lista negada. Ou seja, está negando os caracteres m, a, i, l, t e o, não negando a palavra "mailto". Como o P, de Page, coincide com essa lista negada, ele é ignorado e aparece só "age".

 

ERs não servem para negar strings, apenas letras. Até dá pra fazer um OR usando grupos, mas vira gambiarra. É melhor tirar essa lista da ER, buscar todos os href's e retirar depois os elementos que contenham "mailto". Pode usar strstr() depois de ter o array com todos os links

 

Quanto à dúvida do PS, não entendi. Explique melhor

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado Beraldo,

É... pelo que li por aí é exatamente isso que você falou. Mas por que o P??

Não tem P em "mailto:", como assim ele coincide? Não entendi.

 

O ruim de não manjar das coisas é que soluções mais simples acabam passando batido. rsss

Nem tinha pensado em tratar os resultados depois. Vlw.

 

Quanto ao PS, é que eu coloquei um $key ali pra fazer uma contagem dos resultados, mas ele começa do zero e eu queria que começasse do 1, mas sem omitir o resultado zero. Não tem muita importância isso, é só pra aprender mesmo.

 

Valeu!!

Um dia eu aprendo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado Beraldo,

É... pelo que li por aí é exatamente isso que você falou. Mas por que o P??

Não tem P em "mailto:", como assim ele coincide? Não entendi.

Você criou um lista negada. Ou seja, você procurou por tudo que não fosse "m", "a", "i", "l", "t" e "o". "P" não está nessa lista. Logo, coincide com o padrão

 

 

O ruim de não manjar das coisas é que soluções mais simples acabam passando batido. rsss

Assim que se aprende :)

 

 

Quanto ao PS, é que eu coloquei um $key ali pra fazer uma contagem dos resultados, mas ele começa do zero e eu queria que começasse do 1, mas sem omitir o resultado zero. Não tem muita importância isso, é só pra aprender mesmo.

É só ar echo em ($key + 1) em vez de apenas $key

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você criou um lista negada. Ou seja, você procurou por tudo que não fosse "m", "a", "i", "l", "t" e "o". "P" não está nessa lista. Logo, coincide com o padrão

 

Desculpe, mas continuei sem entender, quer dizer, entendi que eu havia criado a lista negada e que como o Page começa com P e não está na lista ele me mostra seu resultado. Mas por que diabos a primeira letra é omitida nos resultados?

 

E mesmo quando faço o contrário, crio uma lista procurando o "m", ele omite a primeira letra.

Por que isso ocorre? Acho que a primeira letra deveria ser exibida.

 

Obrigado pela paciência Beraldo.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Existem dois tipos de lista:

 

1. Lista comum

2. Lista negada

 

Na lista comum, você coloca entre colchetes todos os caracteres que está procurando. Se quiser procurar por vogais, por exemplo, faria isto: [aeiou].

 

Na lista negada, você coloca entre colchetes, começando com circunflexo (^), os caracteres que não podem coincidir com a ER. Ou seja, se quiser procurar por letras que não sejam vogais, fará isto: [^aeiou]

 

No seu caso, você criou [^mailto]. Ou seja, você procura por qualquer letra que não esteja nessa lista. E "p" não está na lista. Por isso coinicide com a ER

 

Veja mais detalhes aqui:

http://aurelio.net/regex/guia/lista-negada.html#2_1_3

 

Entendeu?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, isso eu tinha entendido.

O que não estou/estava entendendo é por que ele não exibia a letra P, mas acho que agora saquei como o lance funciona.

 

Ele não me mostra a letra P, porque a função entende que eu quero o que está entre o P... assim:

 

$pattern = "/href=\"[^mailto:](.*)\"/";

 

Isso me mostra tudo que estiver ENTRE o href=" e uma letra que não está no [^...] e aquela aspa dupla lá do outro lado.

É isso? :upset:

 

rssss... mais uma vez, obrigado pela paciência e desculpe minha noobisse.

Compartilhar este post


Link para o post
Compartilhar em outros sites

os índices de $matches (3o parâmetro de preg_match_all) terão os valores dos grupos da ER. Grupos são os trechos entre parênteses. No seu caso, a lista negada não está entre parênteses. Por isso o caractere que coincide com ela não é retornado no array $matches.

Retornaria se sua ER fosse esta:

 

/href=\"([^mailto:].*)\"/

 

Note que a lista negada agora está no grupo

 

 

rssss... mais uma vez, obrigado pela paciência e desculpe minha noobisse.

você está fazendo o correto: tirando as dúvidas e entendendo como tudo isso funciona. Errado seria só copiar e colar o código funcionando :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Salve pessoal.

Obrigado pela aula Beraldo.

 

Acho que o menos complicado é montar uma ER pra pegar tudo que estiver dentro do href ou dentro da tag <a>, e depois ir limpando os resultados com o str_replace. Fiz assim e deu certo.

 

Agora estou me batendo pra separar os e-mails de outros links. Gostaria de filtrar os resultados com e sem o @, mas ainda não consegui. Tentei o array_filter e o array_values mas não rolou. Teriam alguma sugestão de como posso fazer isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Usa um pouco de programação funcional.

 

.filter() com um strpos()

Compartilhar este post


Link para o post
Compartilhar em outros sites

Obrigado pela ajuda William.

 

Mas o strpos não me retornaria somente a posição do resultado no array? Eu preciso do resultado em si.

 

Pelo meu conhecimento limitadíssimo, estou optando por voltar as ER e eliminar os e-mail ali mesmo, pois pra pegar tudo e depois ter que filtrar... acho que é mais facil pegar uma coisa de cada vez com o preg_match_all mesmo. Vamos no que eu conheço que acho que vai complicar menos. LOL

 

Estou tentando uma ER

 

$result = "/.*[^@].*/";
ou então
$result= "/href=\"(.*[^@].*)\"/";
Na minha cabeça isso pegaria tudo que não tem o @ no meio, mas, mais uma vez não está rolando.
sugestões?

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Ramael, acho que, inicialmente, há um problema com o seu algoritmo.

Pra mim, o algoritmo correto seria

 

1: Encontrar todos os links

 

2: Selecionar apenas links que não contenham emails

 

O passo um se resolve com uma expressão regular similar (se não for igual) a essa:

 

/href=(["']?)(.*?)(\1|\s|>)/i

 

O segundo passo se resolve aplicando array_filter nos resultados encontrados, como sugerido pelo @William Bruno no post #13

Compartilhar este post


Link para o post
Compartilhar em outros sites

A minha sugestão é isso que o @Evandro Oliveira deixou explicito.

Só rode o filter depois de ter todos os links.

 

Se não, vc terá que rodar 2 ERs full scan, em vez de rodar uma única vez e pegar todos.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Obrigado pessoal!!!

Isso está realmente sendo uma aula.


Beraldo, a ER que você passou não rolou, mas o link é muito maneiro. Agora entendi o porquê daqueles resultados, entendi como os quantificadores gulosos funcionam. Esses guias da Novatec são muito bons, já vou comprar mais alguns.


Evandro, você ajudou a dar uma aprimorada bacana na minha ER. É engraçado que agende aprende um tipo de coisa e tenta fazer somente daquele jeito e não mistura nada. Rsss.

Olha como ficou a ER agora:


$pattern = "/href=[\s\"\'](\s?.*?\s?)[\"\'\s]/i";


Agora além de pegar exatamente o que quero, os hrefs, não importa se o código na página está com algum erro no html o link é pego mesmo assim.


Entendo e concordo com o que você e o William falaram, o ideal e correto é que o se faça somente uma leitura do código e depois se trate o resultado, mas o problema é que eu não conheço praticamente nada de PHP e fico meio tateando no escuro. Se eu conseguisse resolver tudo com ER, então eu não precisaria ficar atormentando tanto vocês. Rsss


Não consegui usar o array_filter e o array_values, na documentação do PHP o texto me parece mais pro técnico do que pro iniciante e também não consegui encontrar muita coisa por aí. Teriam algum lugar mais pro nível iniciante onde consultar? Tentei o site do Aurelio que o Beraldo indicou, mas não achei nada sobre arrays.


Entendam que não quero simplesmente pedir "façam um exemplo", quero minimamente entender o que estou fazendo pra poder usar isso em outras coisas mais pra frente.


vlw pessoal.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendam que não quero simplesmente pedir "façam um exemplo", quero minimamente entender o que estou fazendo pra poder usar isso em outras coisas mais pra frente.

Pode ter certeza que foi esse comportamento que me motivou a interagir com este post

 

Tentei o site do Aurelio que o Beraldo indicou, mas não achei nada sobre arrays.

O guia do Aurelio é exclusivo para expressões regulares e é genérico, independente da linguagem de programação.

 

Não consegui usar o array_filter e o array_values, na documentação do PHP o texto me parece mais pro técnico do que pro iniciante e também não consegui encontrar muita coisa por aí. Teriam algum lugar mais pro nível iniciante onde consultar?

Reproduza os exemplos do manual em um script separado e vá fazendo modificações até ter certeza que entendeu o comportamento da função.

Compartilhar este post


Link para o post
Compartilhar em outros sites

HÁ! Tenho que dizer que estou me sentindo o Daniel San aqui nesse post, maaaaas...

"Consegui!!!" (entre aspas mesmo).

 

Daquele primeiro array feito com o preg_match_all, consegui separar os resultados que quero com o array_filter e o preg_match naquela função callback e aí tome ER novamente!! Fui fazendo como o Evandro disse, testando os pontos do array_filter até "entender".

 

Está ficando bacana, mas ainda estou me batendo com a ER pra não pegar e-mail. LOL

Isso aqui não deveria pegar tudo que não tivesse arroba pelo meio??
$padrao = "/.*?[^@].*?/";

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.