当前位置:  开发笔记 > 编程语言 > 正文

用于提取标记属性的正则表达式

如何解决《用于提取标记属性的正则表达式》经验,为你挑选了7个好方法。

我正在尝试提取锚标记()的属性.到目前为止,我有这样的表达:

(?\b\w+\b)\s*=\s*("(?[^"]*)"|'(?[^']*)'|(?[^"'<> \s]+)\s*)+

适用于字符串之类的


和(单引号)


但不是没有引号的字符串:


如何修改我的正则表达式使其适用于没有引号的属性?或者有更好的方法吗?

谢谢!

更新: 感谢您提供的所有好评和建议.有一件事我没有提到:遗憾的是我必须修补/修改我自己编写的代码.没有时间/金钱可以自下而上重写这些东西.



1> VonC..:

如果你有像这样的元素


此正则表达式可用于连续查找每个属性名称和值

(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?

应用于:




它会产生:

'href' => 'test.html'
'class' => 'xyz'

注意:这不适用于数字属性值,例如

不起作用.


我知道.但是foo的价值将是"bar'bar ='bla"而不仅仅是"bar".
@PauloCosta你可以在https://regex101.com/r/bY3kM1/1看到正则表达式:它会为你解包正则表达式.

2> Axeman..:

虽然不通过regexp解析HTML的建议是有效的,但这里的表达式几乎与您提出的要求相同:

/
   \G                     # start where the last match left off
   (?>                    # begin non-backtracking expression
       .*?                # *anything* until...
       <[Aa]\b            # an anchor tag
    )??                   # but look ahead to see that the rest of the expression
                          #    does not match.
    \s+                   # at least one space
    ( \p{Alpha}           # Our first capture, starting with one alpha
      \p{Alnum}*          # followed by any number of alphanumeric characters
    )                     # end capture #1
    (?: \s* = \s*         # a group starting with a '=', possibly surrounded by spaces.
        (?: (['"])        # capture a single quote character
            (.*?)         # anything else
             \2           # which ever quote character we captured before
        |   ( [^>\s'"]+ ) # any number of non-( '>', space, quote ) chars
        )                 # end group
     )?                   # attribute value was optional
/msx;

"但是等等,"你可能会说."那么*评论呢?!?!" 好的,那么你可以用以下内容替换.非回溯部分:(它还处理CDATA部分.)

(?:[^<]|<[^!]||)

此外,如果您想在Perl 5.10(我认为PCRE)下运行替换,您可以\K在属性名称前面放置,而不必担心捕获您想要跳过的所有内容.



3> Kent Fredric..:

Token Mantra响应:您不应该使用正则表达式调整/修改/收获/或以其他方式生成html/xml.

还有一些必须要考虑的问题,例如"和"这样的极端情况条件.你最好使用适当的DOM解析器,XML解析器,或其他许多经过试验和测试的工具来代替这项工作.发明自己的.

我不关心你使用哪一个,只要它被认可,测试,你使用一个.

my $foo  = Someclass->parse( $xmlstring ); 
my @links = $foo->getChildrenByTagName("a"); 
my @srcs = map { $_->getAttribute("src") } @links; 
# @srcs now contains an array of src attributes extracted from the page. 


是的,HTML的规范声明你应该对它们进行实体编码,但是,由于人们*使用*反斜杠浏览器适应使其工作,并且更多人使用它,因此,你的解析器必须能够在它们执行时处理它: )

4> bobince..:

只是为了与其他人一致:不要使用regexp解析HTML.

不可能创建一个表达式来为即使是正确的HTML片段选择属性,也不要介意所有可能的格式错误的变体.你的正则表达式已经非常难以理解,即使没有尝试应对无效的报价缺失; 进一步追逐真实世界HTML的恐怖,你会因为不可靠的不可靠表达而让自己疯狂.

现有的库可以读取损坏的HTML,或者将其更正为有效的XHTML,然后您可以轻松地使用XML解析器.使用它们.



5> Gumbo..:

您不能对多个捕获使用相同的名称.因此,您不能在具有命名捕获的表达式上使用量词.

所以要么不使用命名捕获:

(?:(\b\w+\b)\s*=\s*("[^"]*"|'[^']*'|[^"'<>\s]+)\s+)+

或者不要在此表达式上使用量词:

(?\b\w+\b)\s*=\s*(?"[^"]*"|'[^']*'|[^"'<>\s]+)

这也允许属性值,如bar=' baz='quux:

foo="bar=' baz='quux"

那么缺点是你必须在之后删除前导和尾随引号.



6> Ivan Chaer..:

PHP(PCRE)和Python

简单的属性提取(见工作):

((?:(?!\s|=).)*)\s*?=\s*?["']?((?:(?<=")(?:(?<=\\)"|[^"])*|(?<=')(?:(?<=\\)'|[^'])*)|(?:(?!"|')(?:(?!\/>|>|\s).)+))

或者使用标记打开/关闭验证,标记名称检索和注释转义.此表达式预见到未加引号/引号,单引号或双引号,属性内的转义引号,等号周围的空格,不同的属性数,仅检查标记内的属性,以及管理属性值中的不同引号.(见工作):

(?:\<\!\-\-(?:(?!\-\-\>)\r\n?|\n|.)*?-\-\>)|(?:<(\S+)\s+(?=.*>)|(?<=[=\s])\G)(?:((?:(?!\s|=).)*)\s*?=\s*?[\"']?((?:(?<=\")(?:(?<=\\)\"|[^\"])*|(?<=')(?:(?<=\\)'|[^'])*)|(?:(?!\"|')(?:(?!\/>|>|\s).)+))[\"']?\s*)

(使用"gisx"标志更好地工作.)


使用Javascript

由于Javascript正则表达式不支持后视,因此它不支持我建议的先前表达式的大多数功能.但是如果它可能符合某人的需要,你可以尝试这个版本.(见工作).

(\S+)=[\'"]?((?:(?!\/>|>|"|\'|\s).)+)



7> Israel Alber..:

这是我提取HTML Tag中的属性的最佳RegEx:

#在引号内修剪匹配项(单引号或双引号)

(\S+)\s*=\s*([']|["])\s*([\W\w]*?)\s*\2

#不带修剪

(\S+)\s*=\s*([']|["])([\W\w]*?)\2

优点:

您可以在引号内修剪内容。

匹配引号内的所有特殊ASCII字符。

如果您具有title =“ You're mine”,则RegEx不会损坏

缺点:

返回3组;首先是属性,然后是引号(“ |”),最后是引号内的属性,即:

结果是第1组:标题,第2组:“,第3组:您是。

这是在线RegEx示例:https : //regex101.com/r/aVz4uG/13



我通常使用此RegEx提取HTML标签:

如果您不使用,等标签类型,则建议您这样做

<[^/]+?(?:\".*?\"|'.*?'|.*?)*?>

例如:

Hello
Nothing # Returns #
#

这是在线RegEx示例:https : //regex101.com/r/aVz4uG/15

此RegEx中的错误是:


在这个标签中:

Hello

返回,

但不应返回任何匹配项:

Match:  

要“解决”此删除[^/]+?模式:




答案#317081很好,但与这些情况不正确匹配:

# It returns "a instead of a
# It doesn't match instead of return only an empty property
# It not recognize the space between the equal (=)

这是改进:

(\S+)\s*=\s*["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))?[^"']*)["']?

(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?

避免等号之间的空格:(\ S +)\ s * = \ s *((?

更改最后的+和。用于:| [>“']))?[^”'] *)[“']?

这是在线RegEx示例:https : //regex101.com/r/aVz4uG/8

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有