正则expression式模式不匹配string中的任何位
我试图匹配使用这种模式的<input>
types“隐藏”字段:
/<input type="hidden" name="([^"]*?)" value="([^"]*?)" />/
这是样本表单数据:
<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="" />
但我不确定type
, name
和value
属性总是以相同的顺序出现。 如果type
属性是最后一个,那么匹配就会失败,因为在我的模式中它是在开始的时候。
题:
我怎样才能改变我的模式,所以它会匹配,而不pipe在<input>
标签中的属性的位置?
PS:顺便说一下,我正在使用基于Adobe Air的RegEx桌面工具来testing正则expression式。
与这里的所有答案相反,对于你想要做的正则expression式是一个完全有效的解决scheme。 这是因为你没有试图匹配平衡标签 – 这是不可能的正则expression式! 但是你只能匹配一个标签中的内容,而且这非常规则。
不过这是问题所在。 你不能只用一个正则expression式来做…你需要做一个匹配来捕获一个<input>
标签,然后对其进行进一步的处理。 请注意,这只有在属性值中没有>
字符的情况下才有效,所以它不是完美的,但它应该足够理智的input。
这里有一些Perl(伪)代码来向你展示我的意思:
my $html = readLargeInputFile(); my @input_tags = $html =~ m/ ( <input # Starts with "<input" (?=[^>]*?type="hidden") # Use lookahead to make sure that type="hidden" [^>]+ # Grab the rest of the tag... \/> # ...except for the />, which is grabbed here )/xgm; # Now each member of @input_tags is something like <input type="hidden" name="SaveRequired" value="False" /> foreach my $input_tag (@input_tags) { my $hash_ref = {}; # Now extract each of the fields one at a time. ($hash_ref->{"name"}) = $input_tag =~ /name="([^"]*)"/; ($hash_ref->{"value"}) = $input_tag =~ /value="([^"]*)"/; # Put $hash_ref in a list or something, or otherwise process it }
这里的基本原则是,不要用一个正则expression式来做太多事情。 正如你注意到的,正则expression式强制执行一定的顺序。 所以你需要做的是首先匹配你想要提取的内容的上下文,然后对你想要的数据进行submatching。
编辑:但是,我会同意,一般来说,使用HTMLparsing器可能更容易,更好,你真的应该考虑重新devise你的代码或重新检查你的目标。 :-)但是,我不得不把这个答案作为一个反应,以解决任何HTML的子集是不可能的:当你考虑整个规范时,HTML和XML都是不规则的,但是标签的规范是体面的规则当然在PCRE的力量之内。
哦,是的,你可以使用正则expression式来parsingHTML!
对于你正在尝试的任务,正则expression式是非常好的!
确实,大多数人低估了用正则expression式parsingHTML的难度,因此做得不好。
但这并不是计算理论的一个基本缺陷。 这个愚蠢的地方在这里很多,但是你不相信他们。
所以虽然这当然是可以做到的(这张贴可以作为这个无可辩驳事实的存在certificate),但这并不意味着它应该是。
您必须自行决定是否要完成用正则expression式写一个专用的专用HTMLparsing器的任务。 大多数人不是。
但我是。 ☻
一般基于正则expression式的HTMLparsing解决scheme
首先我将展示用正则expression式分析任意 HTML是多么容易。 完整的程序在本文的最后,但parsing器的核心是:
for (;;) { given ($html) { last when (pos || 0) >= length; printf "\@%d=", (pos || 0); print "doctype " when / \G (?&doctype) $RX_SUBS /xgc; print "cdata " when / \G (?&cdata) $RX_SUBS /xgc; print "xml " when / \G (?&xml) $RX_SUBS /xgc; print "xhook " when / \G (?&xhook) $RX_SUBS /xgc; print "script " when / \G (?&script) $RX_SUBS /xgc; print "style " when / \G (?&style) $RX_SUBS /xgc; print "comment " when / \G (?&comment) $RX_SUBS /xgc; print "tag " when / \G (?&tag) $RX_SUBS /xgc; print "untag " when / \G (?&untag) $RX_SUBS /xgc; print "nasty " when / \G (?&nasty) $RX_SUBS /xgc; print "text " when / \G (?&nontag) $RX_SUBS /xgc; default { die "UNCLASSIFIED: " . substr($_, pos || 0, (length > 65) ? 65 : length); } } }
看看这是多么容易阅读?
正如所写的,它标识了每一块HTML,并告诉它在哪里发现了这一块。 你可以很容易地修改它来做任何你想要的任何给定types的作品,或比这些更特殊的types。
我没有失败的testing用例(左:):我已经成功地在超过100,000个HTML文件上运行这个代码 – 我可以快速轻松地获得每一个HTML代码。 除此之外,我还运行它专门构造打破天真parsing器的文件。
这不是一个天真的parsing器。
哦,我相信这不是完美的,但我还没有设法打破它。 我认为,即使做了一些事情,由于程序结构清晰,修复也很容易适应。 即使正则expression式重的程序应该有结构。
既然这样,让我来谈谈OP的问题。
演示使用正则expression式解决OP的任务
我在下面包含的小html_input_rx
程序产生了下面的输出,所以你可以看到用正则expression式parsingHTML对于你想做的事情来说工作得很好:
% html_input_rx Amazon.com-_Online_Shopping_for_Electronics,_Apparel,_Computers,_Books,_DVDs_\&_more.htm input tag #1 at character 9955: class => "searchSelect" id => "twotabsearchtextbox" name => "field-keywords" size => "50" style => "width:100%; background-color: #FFF;" title => "Search for" type => "text" value => "" input tag #2 at character 10335: alt => "Go" src => "http://g-ecx.images-amazon.comhttp://img.dovov.comG/01/x-locale/common/transparent-pixel._V192234675_.gif" type => "image"
parsinginput标签,请参见无恶意input
这是产生上面输出的程序的源代码。
#!/usr/bin/env perl # # html_input_rx - pull out all <input> tags from (X)HTML src # via simple regex processing # # Tom Christiansen <tchrist@perl.com> # Sat Nov 20 10:17:31 MST 2010 # ################################################################ use 5.012; use strict; use autodie; use warnings FATAL => "all"; use subs qw{ see_no_evil parse_input_tags input descape dequote load_patterns }; use open ":std", IN => ":bytes", OUT => ":utf8"; use Encode qw< encode decode >; ########################################################### parse_input_tags see_no_evil input ########################################################### until eof(); sub parse_input_tags { my $_ = shift(); our($Input_Tag_Rx, $Pull_Attr_Rx); my $count = 0; while (/$Input_Tag_Rx/pig) { my $input_tag = $+{TAG}; my $place = pos() - length ${^MATCH}; printf "input tag #%d at character %d:\n", ++$count, $place; my %attr = (); while ($input_tag =~ /$Pull_Attr_Rx/g) { my ($name, $value) = @+{ qw< NAME VALUE > }; $value = dequote($value); if (exists $attr{$name}) { printf "Discarding dup attr value '%s' on %s attr\n", $attr{$name} // "<undef>", $name; } $attr{$name} = $value; } for my $name (sort keys %attr) { printf " %10s => ", $name; my $value = descape $attr{$name}; my @Q; given ($value) { @Q = qw[ " " ] when !/'/ && !/"/; @Q = qw[ " " ] when /'/ && !/"/; @Q = qw[ ' ' ] when !/'/ && /"/; @Q = qw[ q( ) ] when /'/ && /"/; default { die "NOTREACHED" } } say $Q[0], $value, $Q[1]; } print "\n"; } } sub dequote { my $_ = $_[0]; s{ (?<quote> ["'] ) (?<BODY> (?s: (?! \k<quote> ) . ) * ) \k<quote> }{$+{BODY}}six; return $_; } sub descape { my $string = $_[0]; for my $_ ($string) { s{ (?<! % ) % ( \p{Hex_Digit} {2} ) }{ chr hex $1; }gsex; s{ & \043 ( [0-9]+ ) (?: ; | (?= [^0-9] ) ) }{ chr $1; }gsex; s{ & \043 x ( \p{ASCII_HexDigit} + ) (?: ; | (?= \P{ASCII_HexDigit} ) ) }{ chr hex $1; }gsex; } return $string; } sub input { our ($RX_SUBS, $Meta_Tag_Rx); my $_ = do { local $/; <> }; my $encoding = "iso-8859-1"; # web default; wish we had the HTTP headers :( while (/$Meta_Tag_Rx/gi) { my $meta = $+{META}; next unless $meta =~ m{ $RX_SUBS (?= http-equiv ) (?&name) (?&equals) (?= (?"e)? content-type ) (?&value) }six; next unless $meta =~ m{ $RX_SUBS (?= content ) (?&name) (?&equals) (?<CONTENT> (?&value) ) }six; next unless $+{CONTENT} =~ m{ $RX_SUBS (?= charset ) (?&name) (?&equals) (?<CHARSET> (?&value) ) }six; if (lc $encoding ne lc $+{CHARSET}) { say "[RESETTING ENCODING $encoding => $+{CHARSET}]"; $encoding = $+{CHARSET}; } } return decode($encoding, $_); } sub see_no_evil { my $_ = shift(); s{ <! DOCTYPE .*? > }{}sx; s{ <! \[ CDATA \[ .*? \]\] > }{}gsx; s{ <script> .*? </script> }{}gsix; s{ <!-- .*? --> }{}gsx; return $_; } sub load_patterns { our $RX_SUBS = qr{ (?(DEFINE) (?<nv_pair> (?&name) (?&equals) (?&value) ) (?<name> \b (?= \pL ) [\w\-] + (?<= \pL ) \b ) (?<equals> (?&might_white) = (?&might_white) ) (?<value> (?"ed_value) | (?&unquoted_value) ) (?<unwhite_chunk> (?: (?! > ) \S ) + ) (?<unquoted_value> [\w\-] * ) (?<might_white> \s * ) (?<quoted_value> (?<quote> ["'] ) (?: (?! \k<quote> ) . ) * \k<quote> ) (?<start_tag> < (?&might_white) ) (?<end_tag> (?&might_white) (?: (?&html_end_tag) | (?&xhtml_end_tag) ) ) (?<html_end_tag> > ) (?<xhtml_end_tag> / > ) ) }six; our $Meta_Tag_Rx = qr{ $RX_SUBS (?<META> (?&start_tag) meta \b (?: (?&might_white) (?&nv_pair) ) + (?&end_tag) ) }six; our $Pull_Attr_Rx = qr{ $RX_SUBS (?<NAME> (?&name) ) (?&equals) (?<VALUE> (?&value) ) }six; our $Input_Tag_Rx = qr{ $RX_SUBS (?<TAG> (?&input_tag) ) (?(DEFINE) (?<input_tag> (?&start_tag) input (?&might_white) (?&attributes) (?&might_white) (?&end_tag) ) (?<attributes> (?: (?&might_white) (?&one_attribute) ) * ) (?<one_attribute> \b (?&legal_attribute) (?&might_white) = (?&might_white) (?: (?"ed_value) | (?&unquoted_value) ) ) (?<legal_attribute> (?: (?&optional_attribute) | (?&standard_attribute) | (?&event_attribute) # for LEGAL parse only, comment out next line | (?&illegal_attribute) ) ) (?<illegal_attribute> (?&name) ) (?<required_attribute> (?#no required attributes) ) (?<optional_attribute> (?&permitted_attribute) | (?&deprecated_attribute) ) # NB: The white space in string literals # below DOES NOT COUNT! It's just # there for legibility. (?<permitted_attribute> accept | alt | bottom | check box | checked | disabled | file | hidden | image | max length | middle | name | password | radio | read only | reset | right | size | src | submit | text | top | type | value ) (?<deprecated_attribute> align ) (?<standard_attribute> access key | class | dir | ltr | id | lang | style | tab index | title | xml:lang ) (?<event_attribute> on blur | on change | on click | on dbl click | on focus | on mouse down | on mouse move | on mouse out | on mouse over | on mouse up | on key down | on key press | on key up | on select ) ) }six; } UNITCHECK { load_patterns(); } END { close(STDOUT) || die "can't close stdout: $!"; }
你走了! 没有什么! 🙂
只有你可以判断你的正则expression式技能是否适合任何特定的parsing任务。 每个人的技能水平都不一样,每个新的任务都不一样。 对于你有明确定义的input集合的工作,正则expression式显然是正确的select,因为当你有限制的HTML子集处理时,把它们放在一起是很简单的。 即使是正则expression式初学者也应该用正则expression式来处理这些工作。 其他任何东西都是矫枉过正的。
但是 ,一旦HTML开始变得不那么明确了,一旦开始出现分歧,你不能预测,但哪一个是完全合法的,一旦你必须匹配更多不同types的东西或更复杂的依赖关系,你最终会达到一个点你必须更努力地使用正则expression式的解决scheme,而不是使用parsing类。 盈亏平衡点的下降又取决于你自己的舒适程度与正则expression式。
所以我该怎么做?
我不会告诉你你必须做什么或者你不能做什么。 我认为这是错误的。 我只是想向你展示可能性,睁开你的眼睛。 你可以select你想要做什么以及你想做什么。 没有绝对的 – 没有人知道你自己的情况,以及你自己做的。 如果看起来有太多的工作,好吧,也许是这样。 编程应该很有趣 ,你知道的。 如果不是的话,你可能会做错了。
可以用任何有效的方法查看我的html_input_rx
程序。 其中之一就是确实可以用正则expression式parsingHTML。 但另外一个就是比几乎所有人都认为的要难得多。 这很容易得出结论,我的程序是对你不应该做的事情的certificate,因为它太难了。
我不会不同意这一点。 当然,如果我的程序中所做的一切都经过一番研究后对你没有意义,那么你不应该试图用正则expression式来完成这种任务。 对于特定的HTML,正则expression式是很好的,但对于通用的HTML,他们无异于疯狂。 我总是使用parsing类,尤其是如果它是HTML我还没有生成自己的。
正则expression式适用于小型 HTMLparsing问题,对于大型parsing问题是最佳的
即使我的程序是为了说明为什么你不应该使用正则expression式来parsing一般的HTML – 这是可以的,因为我的意思是这样做 – – 它仍然应该是一个令人大开眼界,所以更多的人打破了非常常见的以及编写不可读,非结构化和不可维护的模式的讨厌,讨厌的习惯。
模式不一定是丑陋的,他们不必很难。 如果你创造了丑陋的模式,这是对你的反映,而不是他们。
现象精妙的正则expression式语言
我被要求指出,我的proferred问题解决scheme是用Perl编写的。 你惊喜吗? 你没有注意到吗? 这个启示是一个重磅炸弹吗?
我必须承认,我觉得这个要求是极其奇怪的,因为任何不能从我的程序的第一行看出来的人肯定也有其他的精神残疾。
诚然,并不是所有的其他工具和编程语言都像Perl一样,对于正则expression式来说是非常方便,有performance力和强大的。 有一个很大的频谱,有些比其他更合适。 一般来说,将正则expression式作为核心语言的一部分而不是作为库来使用的语言更容易处理。 我没有做任何与你无法做到的正则expression式,例如PCRE,但是如果你使用C,那么你将会构造不同的程序。
最终,其他语言将在Perl的正则expression式方面赶上Perl。 我之所以这样说,是因为当Perl开始时,没有其他人像Perl的正则expression式那样。 你可以说任何你喜欢的东西,但这正是Perl清楚地赢得的地方:每个人都在复制Perl的正则expression式,尽pipe它们处于不同的发展阶段。 Perl几乎不是所有的东西,而是几乎所有的东西,无论你使用什么工具或语言,你现在都依赖于现代模式。 所以最终其他人会赶上。
但是他们只能赶上Perl过去的某个时刻,就像现在一样。 一切都在进步 在正则expression式中,如果没有其他的Perl引导,其他人会遵循。 一旦其他人终于赶上了Perl现在的位置,Perl会在哪里? 我不知道,但我知道我们也会感动的。 也许我们会更接近Perl 6的手工制作模式 。
如果你喜欢这样的事情,但想在Perl 5中使用它,你可能会对Damian Conway的Regexp :: Grammars模块感兴趣。 这是完全可怕的,并使我在我的程序中所做的事情看起来与我的原始模式一样,让人们挤在一起,没有空白或字母标识符。 一探究竟!
简单的HTML Chunker
下面是我在本文开头介绍的parsing器的完整源代码。
我并不是build议你通过严格testing的parsing类来使用它。 但是我厌倦了假装没有人能用正则expression式来parsingHTML,只是因为他们不能。 你显然可以,而这个程序就是这个断言的certificate。
当然,这并不容易,但这是可能的!
试图这样做是一个可怕的浪费时间,因为良好的parsing类存在,你应该使用这个任务。 试图parsing任意 HTML的人的正确答案并不是不可能的。 这是一个轻率和不诚实的答案。 正确和诚实的答案是,他们不应该尝试,因为它从头开始是太麻烦了; 他们不应该为了获得一个完美的轮子而努力。
另一方面,属于可预测子集的 HTML是非常容易用正则expression式parsing的。 难怪人们试图使用它们,因为对于小问题,玩具问题或许没有什么可能更容易。 这就是为什么区分这两个任务非常重要 – 特定与通用 – 因为这不一定要求相同的方法。
我希望将来能够在这里看到对HTML和正则expression式问题的更公平和诚实的处理。
这是我的HTML词法分析器。 它不会尝试进行validation分析; 它只是识别词汇元素。 你可能会认为它比HTMLparsing器更像HTML chunker 。 虽然在这个方向上有一些很小的限制,但它并不能很好地解决HTML的问题。
即使你从来没有自己parsing完整的HTML(为什么你应该?这是一个解决的问题!),这个程序有很多很酷的正则expression式,我相信很多人可以从中学到很多东西。 请享用!
#!/usr/bin/env perl # # chunk_HTML - a regex-based HTML chunker # # Tom Christiansen <tchrist@perl.com # Sun Nov 21 19:16:02 MST 2010 ######################################## use 5.012; use strict; use autodie; use warnings qw< FATAL all >; use open qw< IN :bytes OUT :utf8 :std >; MAIN: { $| = 1; lex_html(my $page = slurpy()); exit(); } ######################################################################## sub lex_html { our $RX_SUBS; ############### my $html = shift(); # Am I... # for (;;) { # forgiven? :)# given ($html) { ############### last when (pos || 0) >= length; printf "\@%d=", (pos || 0); print "doctype " when / \G (?&doctype) $RX_SUBS /xgc; print "cdata " when / \G (?&cdata) $RX_SUBS /xgc; print "xml " when / \G (?&xml) $RX_SUBS /xgc; print "xhook " when / \G (?&xhook) $RX_SUBS /xgc; print "script " when / \G (?&script) $RX_SUBS /xgc; print "style " when / \G (?&style) $RX_SUBS /xgc; print "comment " when / \G (?&comment) $RX_SUBS /xgc; print "tag " when / \G (?&tag) $RX_SUBS /xgc; print "untag " when / \G (?&untag) $RX_SUBS /xgc; print "nasty " when / \G (?&nasty) $RX_SUBS /xgc; print "text " when / \G (?&nontag) $RX_SUBS /xgc; default { die "UNCLASSIFIED: " . substr($_, pos || 0, (length > 65) ? 65 : length); } } } say "."; } ##################### # Return correctly decoded contents of next complete # file slurped in from the <ARGV> stream. # sub slurpy { our ($RX_SUBS, $Meta_Tag_Rx); my $_ = do { local $/; <ARGV> }; # read all input return unless length; use Encode qw< decode >; my $bom = ""; given ($_) { $bom = "UTF-32LE" when / ^ \xFf \xFe \0 \0 /x; # LE $bom = "UTF-32BE" when / ^ \0 \0 \xFe \xFf /x; # BE $bom = "UTF-16LE" when / ^ \xFf \xFe /x; # le $bom = "UTF-16BE" when / ^ \xFe \xFf /x; # be $bom = "UTF-8" when / ^ \xEF \xBB \xBF /x; # st00pid } if ($bom) { say "[BOM $bom]"; s/^...// if $bom eq "UTF-8"; # st00pid # Must use UTF-(16|32) w/o -[BL]E to strip BOM. $bom =~ s/-[LB]E//; return decode($bom, $_); # if BOM found, don't fall through to look # for embedded encoding spec } # Latin1 is web default if not otherwise specified. # No way to do this correctly if it was overridden # in the HTTP header, since we assume stream contains # HTML only, not also the HTTP header. my $encoding = "iso-8859-1"; while (/ (?&xml) $RX_SUBS /pgx) { my $xml = ${^MATCH}; next unless $xml =~ m{ $RX_SUBS (?= encoding ) (?&name) (?&equals) (?"e) ? (?<ENCODING> (?&value) ) }sx; if (lc $encoding ne lc $+{ENCODING}) { say "[XML ENCODING $encoding => $+{ENCODING}]"; $encoding = $+{ENCODING}; } } while (/$Meta_Tag_Rx/gi) { my $meta = $+{META}; next unless $meta =~ m{ $RX_SUBS (?= http-equiv ) (?&name) (?&equals) (?= (?"e)? content-type ) (?&value) }six; next unless $meta =~ m{ $RX_SUBS (?= content ) (?&name) (?&equals) (?<CONTENT> (?&value) ) }six; next unless $+{CONTENT} =~ m{ $RX_SUBS (?= charset ) (?&name) (?&equals) (?<CHARSET> (?&value) ) }six; if (lc $encoding ne lc $+{CHARSET}) { say "[HTTP-EQUIV ENCODING $encoding => $+{CHARSET}]"; $encoding = $+{CHARSET}; } } return decode($encoding, $_); } ######################################################################## # Make sure to this function is called # as soon as source unit has been compiled. UNITCHECK { load_rxsubs() } # useful regex subroutines for HTML parsing sub load_rxsubs { our $RX_SUBS = qr{ (?(DEFINE) (?<WS> \s * ) (?<any_nv_pair> (?&name) (?&equals) (?&value) ) (?<name> \b (?= \pL ) [\w:\-] + \b ) (?<equals> (?&WS) = (?&WS) ) (?<value> (?"ed_value) | (?&unquoted_value) ) (?<unwhite_chunk> (?: (?! > ) \S ) + ) (?<unquoted_value> [\w:\-] * ) (?<any_quote> ["'] ) (?<quoted_value> (?<quote> (?&any_quote) ) (?: (?! \k<quote> ) . ) * \k<quote> ) (?<start_tag> < (?&WS) ) (?<html_end_tag> > ) (?<xhtml_end_tag> / > ) (?<end_tag> (?&WS) (?: (?&html_end_tag) | (?&xhtml_end_tag) ) ) (?<tag> (?&start_tag) (?&name) (?: (?&WS) (?&any_nv_pair) ) * (?&end_tag) ) (?<untag> </ (?&name) > ) # starts like a tag, but has screwed up quotes inside it (?<nasty> (?&start_tag) (?&name) .*? (?&end_tag) ) (?<nontag> [^<] + ) (?<string> (?"ed_value) ) (?<word> (?&name) ) (?<doctype> <!DOCTYPE # please don't feed me nonHTML ### (?&WS) HTML [^>]* > ) (?<cdata> <!\[CDATA\[ .*? \]\] > ) (?<script> (?= <script ) (?&tag) .*? </script> ) (?<style> (?= <style ) (?&tag) .*? </style> ) (?<comment> <!-- .*? --> ) (?<xml> < \? xml (?: (?&WS) (?&any_nv_pair) ) * (?&WS) \? > ) (?<xhook> < \? .*? \? > ) ) }six; our $Meta_Tag_Rx = qr{ $RX_SUBS (?<META> (?&start_tag) meta \b (?: (?&WS) (?&any_nv_pair) ) + (?&end_tag) ) }six; } # nobody *ever* remembers to do this! END { close STDOUT }
- 你可以写一个像tchrist一样的小说
- 您可以使用DOM库,加载HTML并使用xpath,并使用
//input[@type="hidden"]
。 或者,如果您不想使用xpath,只需获取所有input并使用getAttribute
过滤哪些input。
我更喜欢#2。
<?php $d = new DOMDocument(); $d->loadHTML( ' <p>fsdjl</p> <form><div>fdsjl</div></form> <input type="hidden" name="blah" value="hide yo kids"> <input type="text" name="blah" value="hide yo kids"> <input type="hidden" name="blah" value="hide yo wife"> '); $x = new DOMXpath($d); $inputs = $x->evaluate('//input[@type="hidden"]'); foreach ( $inputs as $input ) { echo $input->getAttribute('value'), '<br>'; }
结果:
hide yo kids<br>hide yo wife<br>
本着Tom Christiansen的词法分析器解决scheme的精神,这里是罗伯特·卡梅隆(Robert Cameron)似乎被遗忘的1998年文章的一个链接, REX:使用正则expression式的XML浅parsing。
http://www.cs.sfu.ca/~cameron/REX.html
抽象
XML的语法非常简单,可以使用单个正则expression式将XML文档parsing为其标记和文本项列表。 XML文档的这种浅层分析对于构build各种轻量级XML处理工具可能非常有用。 然而,复杂的正则expression式可能难以构build,甚至更难以阅读。 本文使用正规expression式的文本编程forms,描述了一组XML浅析parsingexpression式,这些expression式可以作为简单,正确,高效,健壮和独立于语言的XML浅parsing的基础。 在Perl,JavaScript和Lex / Flex中,还给出了less于50行的浅parsing器实现。
如果你喜欢阅读正则expression式,卡梅隆的文章是迷人的。 他的写作简洁,深入,非常详细。 他不是简单地向您展示如何构buildREX正则expression式,而且也是从小部分构build任何复杂正则expression式的方法。
我一直在使用REX正则expression式10年来解决最初的海报问(如何匹配这个特定的标签,但不是一些其他非常类似的标签?)的问题。 我发现他开发的正则expression式是完全可靠的。
当你关注文档的词汇细节时(例如,将一种文本文档(如纯文本,XML,SGML,HTML)转换为另一种文档可能无效时),REX特别有用,良好的形成,甚至可以parsing大部分的转换。 它可以让你在文档中的任何位置定位标记岛而不会干扰文档的其他部分。
虽然我喜欢其他答案的内容,但他们并没有真正直接或正确地回答这个问题。 即使白金的答案过于复杂,效率也不高。 所以我被迫把这个。
正确使用时,我是正则expression式的巨大支持者。 但是由于耻辱(和性能),我总是声明格式正确的XML或HTML应该使用XMLparsing器。 甚至更好的性能将是stringparsing,尽pipe如果这太可手可得,那么在可读性之间存在一条线。 但是,这不是问题。 问题是如何匹配隐藏types的input标签。 答案是:
<input[^>]*type="hidden"[^>]*>
根据你的风格,你需要包括的唯一的正则expression式选项是ignorecase选项。
you can try this :
<[A-Za-z ="/_0-9+]*>
and for closer result you can try this :
<[ ]*input[ ]+type="hidden"[ ]*name=[A-Za-z ="_0-9+]*[ ]*[/]*>
you can test your regex pattern here http://regexpal.com/
these pattens are good for this:
<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" />
and for random order of type
, name
and value
u can use this :
<[ ]*input[ ]*[A-Za-z ="_0-9+/]*>
要么
<[ ]*input[ ]*[A-Za-z ="_0-9+/]*[ ]*[/]>
on this :
<input name="SaveRequired" type="hidden" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input name="__VIEWSTATE3" type="hidden" value="ZVVV91yjY" />
`
by the way i think you want something like this :
<[ ]*input(([ ]*type="hidden"[ ]*name=[A-Za-z0-9_+"]*[ ]*value=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*type="hidden"[ ]*value=[A-Za-z0-9_+"]*[ ]*name=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*name=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*value=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*value=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*name=[A-Za-z0-9_+"]*[ ]*)+)[ ]*/>|<[ ]*input(([ ]*name=[A-Za-z0-9_+"]*[ ]*value=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*)+)[ ]*/>|<[ ]*input(([ ]*value=[A-Za-z0-9_+"]*[ ]*name=[A-Za-z0-9_+"]*[ ]*type="hidden"[ ]*)+)[ ]*/>
its not good but it works in any way.
test it in : http://regexpal.com/
I would like to use **DOMDocument**
to extract the html code.
$dom = new DOMDocument(); $dom ->loadHTML($input); $x = new DOMXpath($dom ); $results = $x->evaluate('//input[@type="hidden"]'); foreach ( $results as $item) { print_r( $item->getAttribute('value') ); }
BTW, you can test it in here – regex101.com. It shows the result at real time. Some rules about Regexp: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html Reader .
suppose your html content is stored in string html then in order to get every input that contain type hidden you can use regular expression
var regex = /(<input.*?type\s?=\s?["']hidden["'].*?>)/g; html.match(regex);
the above regex find <input
followed by any number of characters until it gets type="hidden"
or type='hidden' followed by any number of characters till it gets >
/g tell regular expression to find every substring that matches to the given pattern.