正则表达式模式不匹配字符串中的任何位

我正在尝试使用此模式匹配<input>类型的“hidden”字段:

/<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="" />

但我不确定typenamevalue属性总是以相同的顺序出现。 如果type属性最后一次出现,则匹配将失败,因为在我的模式中它是在开始处。

题:
我怎样才能改变我的模式,使它匹配而不管<input>标签中属性的位置?

PS:顺便说一下,我使用基于Adobe Air的RegEx桌面工具来测试正则表达式。


与这里的所有答案相反,对于你想要做的正则表达式是一个完美的有效解决方案。 这是因为你并不想匹配平衡标签 - 这对于正则表达式是不可能的! 但是你只能匹配一个标签中的内容,而且这非常规则。

不过,这是问题所在。 你不能用一个正则表达式来做......你需要做一个匹配来捕获一个<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
}

这里的基本原则是,不要试图用一个正则表达式做太多。 正如你注意到的那样,正则表达式强制执行一定的顺序。 所以你需要做的是首先匹配你想要提取的内容的CONTEXT,然后对你想要的数据进行匹配。

编辑:但是,我会同意,一般来说,使用HTML解析器可能更容易,更好,你真的应该考虑重新设计你的代码或重新检查你的目标。 :-)但是我不得不把这个答案作为对膝盖反应的反应,即解析HTML的任何子集是不可能的:当你考虑整个规范时,HTML和XML都是不规则的,但是标签的规范是正规的,当然在PCRE的力量之内。


哦,是的,你可以使用正则表达式来解析HTML!

对于你正在尝试的任务,正则表达式非常好!

确实,大多数人低估了用正则表达式解析HTML的难度,因此做得很差。

但这不是与计算理论相关的一些基本缺陷。 这种愚蠢在这里很多,但你不相信它们。

所以虽然它当然可以完成(这张贴可以作为这一无可辩驳的事实的存在证明),但这并不意味着它应该如此。

您必须自行决定是否要完成用正则表达式编写专门用途的专用HTML解析器的任务。 大多数人不是。

但我是。 ☻


一般基于正则表达式的HTML解析解决方案

首先我将展示用正则表达式解析任意 HTML是多么容易。 完整的程序在本文末尾,但解析器的核心是:

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,并告诉它在哪里找到了这一块。 你可以很容易地修改它,以完成任何你想要的任何其他类型的作品,或者比这些更特别的类型。

我没有失败的测试用例(左:):我已成功在超过100,000个HTML文件上运行此代码 - 我可以快速轻松地获得每一个HTML代码。 除此之外,我还将其运行在特别构建的文件上以打破天真的解析器。

这不是一个天真的解析器。

哦,我相信这不是完美的,但我还没有设法打破它。 我认为,即使做了某些事情,由于该计划的结构清晰,修复工作很容易适应。 即使是正则表达式程序也应该有结构。

既然这样,让我谈谈OP的问题。

演示使用正则表达式解决OP的任务

我在下面包含的小html_input_rx程序产生以下输出,以便您可以看到使用正则表达式解析HTML对于您想要执行的操作来说工作得很好:

% 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.com/images/G/01/x-locale/common/transparent-pixel._V192234675_.gif"
        type => "image"

解析输入标签,请参见无恶意输入

这是产生上述输出的程序的源代码。

#!/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 attrn",
                    $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{
            & 43 
            ( [0-9]+ )
            (?: ; 
              | (?= [^0-9] )
            )
        }{
            chr     $1;
        }gsex;
        s{
            & 43 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) 
            (?= (?&quote)? 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>           (?&quoted_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) 
                (?:
                    (?&quoted_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: $!";
} 

你走了! 什么都没有! :)

只有可以判断您的正则表达式技能是否取决于任何特定的解析任务。 每个人的技能水平都不一样,每个新任务都不一样。 对于有明确定义的输入集的工作,正则表达式显然是正确的选择,因为当你有限制的HTML子集进行处理时,把它们放在一起很不重要。 即使是正则表达式初学者也应该用正则表达式处理这些工作。 其他任何东西都是矫枉过正的。

然而 ,一旦HTML开始变得不那么简单,一旦它开始以不可预测的方式产生分歧,但是哪些是完全合法的,一旦你必须匹配更多不同类型的事物或更复杂的依赖关系,你最终会达到一个点您必须更努力地使用正则表达式来实现解决方案,而不是使用解析类。 盈亏平衡点下降的地方又取决于你自己的舒适度和正则表达式。

所以我该怎么做?

我不会告诉你你必须做什么或者你不能做什么。 我认为这是错误的。 我只是想向你展示可能性,睁开你的眼睛。 你可以选择你想要做什么以及你想做什么。 没有绝对的 - 没有人知道你自己的情况,以及你自己做的。 如果看起来有太多的工作,好吧,也许是这样。 编程应该很有趣 ,你知道的。 如果不是,你可能会做错。

可以用任何有效的方法查看我的html_input_rx程序。 其中一个就是你确实可以用正则表达式解析HTML。 但另一个原因是它比几乎任何人都认为它要困难得多。 这很容易导致这样的结论:我的程序是对你不应该做的事情的证明,因为它确实太难了。

我不会不同意这一点。 当然,如果我的程序中所做的每件事都经过一些研究后对你没有意义,那么你不应该试图用正则表达式来完成这种任务。 对于特定的HTML,正则表达式很好,但对于泛型HTML,它们无异于疯狂。 我总是使用解析类,尤其是如果它是HTML,我还没有生成自己。

正则表达式适用于小型HTML解析问题,对于大型问题最好

即使我的节目被认为是说明性的,为什么你应该使用正则表达式解析普通HTML -这是OK的,因为我还挺意味着它是☺ -它仍然应该是一个大开眼界让更多的人打破了非常常见的以及编写不可读,非结构化和不可维护的模式的讨厌习惯。

模式不一定很难看,而且也不一定很难。 如果你创造出丑陋的模式,这是对你的反映,而不是他们。

奇妙的正则表达式语言

我被要求指出,我对你的问题所提出的杰出解决方案是用Perl编写的。 你惊喜吗? 你没注意到吗? 这个启示是否是一个重磅炸弹?

我必须承认,我觉得这个要求极其怪异,因为任何无法从我的程序的第一行看出来的人肯定也有其他精神残疾。

诚然,并非所有其他工具和编程语言都像Perl一样,对于正则表达式而言非常方便,表达和强大。 有一个很大的频谱,有些比其他更合适。 一般来说,表达正则表达式作为核心语言的一部分而不是库的语言更容易处理。 我没有采用任何你无法完成的正则表达式,例如PCRE,尽管如果你使用C语言,你会以不同的方式构造程序。

最终,其他语言将在正则表达式方面赶上Perl的位置。 我之所以这么说,是因为当Perl开始时,没有人像Perl的正则表达式那样。 说出你喜欢的任何东西,但这是Perl明显赢得的地方:每个人都复制Perl的正则表达式,尽管它们处于不同的开发阶段。 无论您使用什么工具或语言,Perl几乎(不是全部,但几乎)都是您今天在现代模式中依赖的一切。 所以最终其他人会赶上。

但是它们只能赶上Perl过去的某个时刻,就像现在一样。 一切都在前进 在正则表达式中,如果没有其他的东西,Perl领先,其他人会遵循。 一旦其他人最终赶上Perl现在的位置,Perl会在哪里? 我不知道,但我知道我们也会感动。 可能我们会更接近Perl 6的手工制作模式。

如果你喜欢之类的话,但想在Perl₅使用它,你可能会感兴趣的Damian Conway的精彩正则表达式语法::模块。 这是完全可怕的,并且使我在我的程序中完成的工作看起来与我的原始模式一样,使得人们无需空格或字母标识就可以拼凑在一起。 一探究竟!


简单的HTML Chunker

以下是我在本文开头部分展示的核心内容的解析器的完整源代码。

我并不是建议你通过严格测试的解析类来使用它。 但我厌倦了假装没人能用正则表达式解析HTML的人,因为他们不能。 你显然可以,而这个程序就是这个断言的证明。

当然,这并不容易,但它是可能的!

并且试图这样做会浪费时间,因为存在您应该用于此任务的良好解析类。 试图解析任意HTML的人的正确答案并不是不可能的。 这是一个轻率和不诚实的答案。 正确和诚实的答案是,他们不应该尝试它,因为它从头开始是太麻烦了; 他们不应该为了获得完美运转的车轮而努力挣扎。

另一方面,属于可预测子集的HTML非常容易用正则表达式解析。 难怪人们会尝试使用它们,因为对于小问题,玩具问题也许没有什么比这更容易的了。 这就是为什么区分这两个任务非常重要 - 特定与通用 - 因为这些任务不一定需要相同的方法。

我希望将来能够在这里看到对HTML和正则表达式问题的更公平和诚实的处理。

这是我的HTML词法分析器。 它不会尝试进行验证分析; 它只是识别词汇元素。 你可能会认为它更像HTML解析器不是HTML解析器。 虽然它在这个方向上有一些非常小的限制,但它并不能很好地解决HTML的问题。

即使你永远不会自己解析完整的HTML(为什么你应该?这是一个解决的问题!),这个程序有很多很酷的正则表达式,我相信很多人都可以从中学到很多东西。 请享用!

#!/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       /x;  # LE
        $bom = "UTF-32BE" when / ^       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)
                            (?&quote) ?
            (?<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)
            (?= (?&quote)? 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>           (?&quoted_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> (?&quoted_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,只需获取所有输入并使用getAttribute过滤哪些输入。
  • 我更喜欢#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>
    
    链接地址: http://www.djcxy.com/p/5075.html

    上一篇: Regular expression pattern not matching anywhere in string

    下一篇: style </ in <script> tag