Estou tentando corresponder <input>
os campos do tipo "oculto" usando este padrão:
/<input type="hidden" name="([^"]*?)" value="([^"]*?)" />/
Estes são dados de exemplo de formulário:
<input type="hidden" name="SaveRequired" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input type="hidden" name="__VIEWSTATE3" value="ZVVV91yjY" /><input type="hidden" name="__VIEWSTATE0" value="3" /><input type="hidden" name="__VIEWSTATE" value="" /><input type="hidden" name="__VIEWSTATE" value="" />
Mas não tenho a certeza que o type
, name
, e value
atributos sempre aparecem na mesma ordem. Se o type
atributo vier por último, a correspondência falhará, porque no meu padrão está no início.
Pergunta:
Como posso alterar meu padrão para que ele corresponda, independentemente das posições dos atributos na <input>
tag?
PS: A propósito, estou usando a RegEx Desktop Tool baseada em Adobe Air para testar expressões regulares.
Respostas:
Ao contrário de todas as respostas aqui, o que você está tentando fazer regex é uma solução perfeitamente válida. Isso ocorre porque você NÃO está tentando combinar tags equilibradas - isso seria impossível com a expressão regular! Mas você está apenas combinando o que está em uma tag, e isso é perfeitamente regular.
Aqui está o problema, no entanto. Você não pode fazer isso com apenas um regex ... você precisa fazer uma correspondência para capturar uma
<input>
tag e, posteriormente, fazer um processamento adicional. Observe que isso só funcionará se nenhum dos valores de atributo tiver um>
caractere, portanto, não é perfeito, mas deve ser suficiente para entradas sãs.Aqui está algum código Perl (pseudo) para mostrar o que eu quero dizer:
O princípio básico aqui é: não tente fazer muito com uma expressão regular. Como você notou, expressões regulares impõem uma certa quantidade de ordem. Portanto, o que você precisa fazer é primeiro corresponder ao CONTEXTO do que você está tentando extrair e, em seguida, fazer a sub correspondência dos dados desejados.
EDIT: No entanto, eu concordo que, em geral, o uso de um analisador de HTML é provavelmente mais fácil e melhor e você deve considerar redesenhar seu código ou reexaminar seus objetivos. :-) Mas eu tive que postar esta resposta como uma reação à reação instintiva de que analisar qualquer subconjunto de HTML é impossível: HTML e XML são irregulares quando você considera toda a especificação, mas a especificação de uma tag é decentemente regular , certamente dentro do poder do PCRE.
fonte
Ah, sim, você pode usar expressões regulares para analisar HTML!
Para a tarefa que você está tentando, as expressões regulares estão perfeitamente corretas!
Ele é verdade que a maioria das pessoas subestimam a dificuldade de análise de HTML com expressões regulares e, portanto, fazê-lo mal.
Mas essa não é uma falha fundamental relacionada à teoria computacional. Essa bobagem é muito repetida por aqui , mas você não acredita nelas.
Portanto, embora certamente possa ser feito (essa publicação serve como prova de existência desse fato incontestável), isso não significa que deva ser.
Você deve decidir por si próprio se está preparado para a tarefa de escrever o que equivale a um analisador HTML específico para fins especiais a partir de expressões regulares. A maioria das pessoas não é.
Mas eu sou ☻
Soluções gerais de análise de HTML baseadas em Regex
Primeiro, mostrarei como é fácil analisar HTML arbitrário com expressões regulares. O programa completo está no final desta postagem, mas o coração do analisador é:
Veja como é fácil ler isso?
Como está escrito, ele identifica cada pedaço de HTML e informa onde ele o encontrou. Você pode modificá-lo facilmente para fazer o que quiser com qualquer tipo de peça ou para tipos mais específicos que estes.
Não tenho casos de teste com falha (à esquerda :): executei esse código com êxito em mais de 100.000 arquivos HTML - todos os que consegui com rapidez e facilidade. Além disso, eu também o executei em arquivos construídos especificamente para quebrar analisadores ingênuos.
Este não é um analisador ingênuo.
Ah, tenho certeza de que não é perfeito, mas ainda não consegui quebrá-lo. Eu acho que, mesmo que algo acontecesse, a correção seria fácil de se encaixar por causa da estrutura clara do programa. Mesmo programas pesados em regex devem ter estrutura.
Agora que isso está fora do caminho, deixe-me abordar a questão do OP.
Demonstração de solução de tarefas do OP usando expressões regulares
O pequeno
html_input_rx
programa que incluo abaixo produz a seguinte saída, para que você possa ver que a análise de HTML com regexes funciona bem para o que você deseja fazer:Analisar tags de entrada, consulte Nenhuma entrada incorreta
Aqui está a fonte do programa que produziu a saída acima.
Ai está! Nada disso! :)
Somente você pode julgar se sua habilidade com expressões regulares depende de uma tarefa de análise específica. O nível de habilidade de todos é diferente e cada nova tarefa é diferente. Para trabalhos em que você tem um conjunto de entradas bem definido, as expressões regulares são obviamente a escolha certa, porque é trivial reunir algumas quando você tem um subconjunto restrito de HTML para lidar. Mesmo iniciantes em regex devem lidar com esses trabalhos com regexes. Qualquer outra coisa é um exagero.
No entanto , uma vez que o HTML comece a ficar menos complicado, uma vez que começa a se ramificar de maneiras que você não pode prever, mas que são perfeitamente legais, uma vez que você tenha que combinar tipos diferentes de coisas ou dependências mais complexas, você chegará a um ponto em que você precisa trabalhar mais para efetuar uma solução que use expressões regulares do que para uma classe de análise. O ponto em que esse ponto de equilíbrio cai depende novamente do seu próprio nível de conforto com as expressões regulares.
Então, o que eu deveria fazer?
Não vou lhe dizer o que você deve fazer ou o que não pode fazer. Eu acho que está errado. Eu só quero lhe apresentar possibilidades, abra seus olhos um pouco. Você escolhe o que deseja fazer e como deseja fazê-lo. Não há absolutos - e ninguém mais conhece sua própria situação, assim como você. Se algo parece dar muito trabalho, bem, talvez seja. A programação deve ser divertida , você sabe. Se não estiver, você pode estar fazendo errado.
Pode-se olhar para o meu
html_input_rx
programa de várias maneiras válidas. Uma delas é que você realmente pode analisar HTML com expressões regulares. Mas outra é que é muito, muito, muito mais difícil do que quase todo mundo pensa que é. Isso pode facilmente levar à conclusão de que meu programa é uma prova do que você não deve fazer, porque é realmente muito difícil.Não vou discordar disso. Certamente, se tudo o que faço no meu programa não faz sentido para você depois de algum estudo, você não deve tentar usar expressões regulares para esse tipo de tarefa. Para HTML específico, as expressões regulares são ótimas, mas para HTML genérico, é o mesmo que loucura. Eu uso classes de análise o tempo todo, especialmente se for HTML que eu não tenha gerado.
Regexa ideal para pequenos problemas de análise de HTML, pessimal para grandes
Mesmo que meu programa seja tomado como ilustrativo do motivo pelo qual você não deve usar expressões regulares para analisar HTML geral - o que é bom, porque eu meio que pretendia que fosse isso -, ainda assim deveria ser algo que abre os olhos para que mais pessoas quebrem o padrão comum. e o hábito desagradável de escrever padrões ilegíveis, não estruturados e inatingíveis.
Os padrões não precisam ser feios e não precisam ser difíceis. Se você criar padrões feios, é um reflexo sobre você, não sobre eles.
Linguagem Regex fenomenalmente requintada
Me pediram para salientar que minha solução proferida para o seu problema foi escrita em Perl. Você está surpreso? Você não percebeu? Esta revelação é uma bomba?
É verdade que nem todas as outras ferramentas e linguagens de programação são tão convenientes, expressivas e poderosas quando se trata de expressões regulares quanto o Perl. Há um grande espectro por aí, com alguns sendo mais adequados que outros. Em geral, os idiomas que expressaram expressões regulares como parte do idioma principal e não como uma biblioteca são mais fáceis de trabalhar. Não fiz nada com expressões regulares que você não poderia fazer, por exemplo, no PCRE, embora você estruture o programa de maneira diferente se estiver usando C.
Eventualmente, outros idiomas serão informados sobre o local em que o Perl está agora em termos de expressões regulares. Digo isso porque, quando o Perl começou, ninguém mais tinha nada parecido com as expressões regulares do Perl. Diga o que quiser, mas foi aqui que Perl claramente venceu: todos copiaram as expressões regulares de Perl, embora em estágios variados de seu desenvolvimento. O Perl foi pioneiro em quase (não quase tudo, mas quase) tudo em que você confia nos padrões modernos de hoje, independentemente da ferramenta ou linguagem usada. Então, eventualmente, os outros vão alcançá-lo.
Mas eles só alcançam onde Perl estava em algum momento no passado, exatamente como está agora. Tudo avança. Em regexes, se nada mais, onde Perl leva, outros seguem. Onde estará o Perl depois que todo mundo finalmente alcançar onde está agora? Não faço ideia, mas sei que nós também teremos mudado. Provavelmente estaremos mais próximos do estilo de criação de padrões de Perl₆ .
Se você gosta desse tipo de coisa, mas gostaria de usá-lo em Perl₅, pode estar interessado no maravilhoso módulo Regexp :: Grammars de Damian Conway . É totalmente incrível e faz com que o que eu fiz aqui no meu programa pareça tão primitivo quanto o meu, que faz com que os padrões que as pessoas criam juntos sem espaço em branco ou identificadores alfabéticos. Confira!
Chunker HTML Simples
Aqui está a fonte completa do analisador de onde mostrei a peça central no início desta postagem.
Estou não sugerindo que você deve usar este sobre uma classe analisar rigorosamente testados. Mas estou cansado de pessoas que fingem que ninguém pode analisar HTML com expressões regulares apenas porque não podem. Você pode, claramente, e este programa é a prova dessa afirmação.
Claro, não é fácil, mas isso é possível!
E tentar fazer isso é uma terrível perda de tempo, porque existem boas classes de análise que você deve usar para esta tarefa. A resposta certa para as pessoas que tentam analisar HTML arbitrário não é que seja impossível. Essa é uma resposta fácil e falsa. A resposta correta e honesta é que eles não devem tentar, porque é um incômodo demais descobrir do zero; eles não devem quebrar as costas se esforçando para reativar uma roda que funcione perfeitamente bem.
Por outro lado, o HTML que se enquadra em um subconjunto previsível é extremamente fácil de analisar com expressões regulares. Não é de admirar que as pessoas tentem usá-las, porque, para pequenos problemas, talvez problemas com brinquedos, nada poderia ser mais fácil. É por isso que é tão importante distinguir as duas tarefas - específica e genérica -, pois elas não exigem necessariamente a mesma abordagem.
Espero no futuro aqui ver um tratamento mais justo e honesto das perguntas sobre HTML e expressões regulares.
Aqui está o meu lexer HTML. Ele não tenta fazer uma análise de validação; apenas identifica os elementos lexicais. Você pode pensar nisso mais como um chunker HTML do que como um analisador HTML. Ele não perdoa muito o HTML quebrado, embora faça algumas permissões muito pequenas nessa direção.
Mesmo se você nunca analisar o HTML completo (e por que deveria? É um problema resolvido!), Este programa possui muitos bits legais de regex que acredito que muitas pessoas podem aprender muito. Aproveitar!
fonte
//input[@type="hidden"]
. Ou se você não quiser usar o xpath, obtenha todas as entradas e filtre quais estão ocultasgetAttribute
.Eu prefiro o 2.
Resultado:
fonte
No espírito da solução lexer de Tom Christiansen, aqui está um link para o aparentemente esquecido artigo de Robert Cameron, de 1998, REX: XML Shallow Parsing with Regular Expressions.
http://www.cs.sfu.ca/~cameron/REX.html
Se você gosta de ler sobre expressões regulares, o artigo de Cameron é fascinante. Sua escrita é concisa, completa e muito detalhada. Ele não está simplesmente mostrando como construir a expressão regular REX, mas também uma abordagem para criar qualquer regex complexo a partir de partes menores.
Eu uso a expressão regular REX há 10 anos para resolver o tipo de problema sobre o qual o pôster inicial perguntou (como faço para corresponder a essa tag específica, mas não a uma tag muito semelhante?). Eu encontrei o regex que ele desenvolveu para ser completamente confiável.
O REX é particularmente útil quando você se concentra nos detalhes lexicais de um documento - por exemplo, ao transformar um tipo de documento de texto (por exemplo, texto sem formatação, XML, SGML, HTML) em outro, onde o documento pode não ser válido, bem formado, ou mesmo analisável durante a maior parte da transformação. Permite segmentar ilhas de marcação em qualquer lugar de um documento sem perturbar o restante do documento.
fonte
Embora eu adore o conteúdo das demais respostas, elas não responderam à pergunta direta ou corretamente. Até a resposta da Platinum foi excessivamente complicada e também menos eficiente. Então eu fui forçado a colocar isso.
Sou um grande defensor do Regex, quando usado corretamente. Mas, devido ao estigma (e desempenho), eu sempre declaro que XML ou HTML bem formado deve usar um Analisador de XML. E um desempenho ainda melhor seria a análise de cadeias, embora exista uma linha entre a legibilidade, se isso ficar fora de controle. No entanto, essa não é a questão. A questão é como combinar uma tag de entrada do tipo oculto. A resposta é:
Dependendo do seu sabor, a única opção regex que você precisa incluir é a opção ignecase.
fonte
<input type='hidden' name='Oh, <really>?' value='Try a real HTML parser instead.'>
>
no campo nome sejam quase nenhuma, é realmente possível que exista>
um identificador de ação. EG: Uma chamada javascript embutida na propriedade OnClick. Dito isto, eu tenho um analisador XML para eles, mas também tenho um Regex para aqueles em que o documento que recebo está muito bagunçado para os analisadores XML manipularem, mas um Regex pode. Além disso, não era essa a pergunta. Você nunca encontrará essas situações com uma entrada oculta, e minha resposta é a melhor.Ya, <really>!
./>
é um XML-ism; não é necessário em nenhuma versão do HTML, exceto no XHTML (que nunca ganhou muita força e foi praticamente substituído pelo HTML5). E você está certo de que existe um monte de HTML confuso e não muito válido por aí, mas um bom analisador de HTML ( não XML) deve ser capaz de lidar com a maior parte; se não o fizerem, provavelmente os navegadores também não.você pode tentar isso:
e para obter resultados mais próximos, você pode tentar o seguinte:
você pode testar seu padrão regex aqui http://regexpal.com/
estes pattens são bons para isso:
e por ordem aleatória de
type
,name
evalue
você pode usar isto:ou
nisto :
`
a propósito, eu acho que você quer algo como isto:
não é bom, mas funciona de qualquer maneira.
teste-o em: http://regexpal.com/
fonte
Eu gostaria de usar
**DOMDocument**
para extrair o código html.BTW, você pode testá-lo aqui - regex101.com. Mostra o resultado em tempo real. Algumas regras sobre o Regexp: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html Reader .
fonte
suponha que seu conteúdo html seja armazenado na string html e, a fim de obter todas as entradas que contêm o tipo oculto, você pode usar expressões regulares
o regex acima encontra
<input
seguido por qualquer número de caracteres até que obtenhatype="hidden"
ou digite = 'oculto' seguido por qualquer número de caracteres até que obtenha>
/ g informa a expressão regular para encontrar todas as subseqüências que correspondem ao padrão especificado.
fonte