整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Javascript正则表达式示例之HTML标签及H

Javascript正则表达式示例之HTML标签及HTML语法树

一节聊到正则表达式的简单应用,不足之处欢迎留言交流。

Javascript正则表达式示例之基本概念

今天,我们来看一下,如何使用正则表达式,匹配HTML标签及相关信息。

为什么要加上相关信息呢?

因为,如果您想写一个HTML语法树解析库的时候,可能会用到。


下面内容用到的语法

|:表示或者,要么前面,要么后面

(?<=我前面出现的内容)要匹配的内容:只匹配前面出现的字符之后的内容。

可视图

要匹配的内容(?=我前面出现的内容):只匹配后面出现的字符之前的内容。

可视图

分组捕获:一对完整的小括号(),表示一个组。

\数字:你要使用那一个分组捕获到的内容。

.*?:在正则表达式中,. 表示匹配任意字符,* 表示匹配 0 到任意次的前一个字符,? 表示非贪婪匹配,即尽可能匹配最少的字符。因此,.*? 表示匹配任意字符零次或多次,但尽可能匹配最少的字符。这个表达式通常用于匹配一个字符串中的所有内容,但是避免贪婪匹配导致的匹配错误。

^: 表示匹配开始

[要匹配的字符]:只匹配括号中的字符。

比如[0-9]、[a-z]、[A-Z]、[0-9a-zA-Z]、[0-9abc]等等。

[^要匹配的字符]:[]中加^表示匹配不是“要匹配的字符”。


1、匹配所有HTML标签,并清空。实现innerText类似的功能。

<body><div id="left">left</div><div id="right">right</div></body>
const text=document.body.innerText;
text=text.replace(/\n/g, '');
console.log(text);
//输出: leftright

假设没有innerText的功能呢?实现这个功能,使用正则表达式无疑是最方便的。

var text=document.body.innerHTML.replace(/<[^>]+>/g,'');
text=text.replace(/\n/g, '');
console.log(text);
//输出: leftright

匹配结果

可视图


是的,这个正则表达式的意思是,查找<>并且包含他们之间不为>的一段字符串。

到这里,您以为就结束了吗?您在网上搜索匹配HTML标签,可能也会得到这么一个结果(例如:<[^>]+>、<.*?>、等等),但实际上这只是开始,我们本着只要是程序就可能有bug的原则,所以我们来看下面一个例子。

const strHtml='<span data-code=">">>是大于符号。</span>';
const strRes=strHtml.replace(/<[^>]+>/g, '');
console.log(strRes);
// ">>是大于符号。

[可怜]bug出现了,怎么办?别着急,请看下一个知识点。


2、匹配HTML标签属性,是写一个HTML语法树要经历的事情。


2.1、首先,我们先解决第一点最后的bug。

const strHtml='<span data-code=">">>是大于符号。</span>';
// 一个小改动即可。
const strRes=strHtml.replace(/<("[^"]*"|[^>])+>/g, '');
console.log(strRes);
// >是大于符号。

可视图

完美[打脸] ,还没结束……

const strHtml="<span data-code='>'>>是大于符号。</span>";
const strRes=strHtml.replace(/<("[^"]*"|[^>])+>/g, '');
console.log(strRes);
// '>>是大于符号。

甲:这不是我写的HTML不标准,是你的解析库兼容性不好,浏览器都可以识别,你为什么不可以?

已:……。

const strHtml=`<i code="<"><小于符号。</i><i code='>'>>大于符号。</i>`;
// 继续改造
const strRes=strHtml.replace(/<((["'])+.*?\2|[^>])+>/g, '');
console.log(strRes);
// <小于符号。>大于符号。

匹配结果

可视图

是的,利用正则表达式分组捕获的语法,实现了上面的需求。


2.2 现在,我们来看看,如何找到某个标签的所有属性。

const strHtml=`
<input type='text' disabled value="" class="txt txt-md" v-on:click="save('button')" />
`;

上面的例子中,有多种情况,我们首先来整理出来。

属性1:type='text'

/[\w]+=(["'])+.*?/

属性2:disabled

/[\w]+/

属性3:value=""

/[\w]+=(["'])+.*?/

属性4:class="txt txt-md"

/[\w]+=(["'])+.*?/

属性5:v-on:click="save('button')"

/[\w:]+=(["'])+.*?/

其他情况:欢迎讨论。

把所有情况连起来之后。

const strHtml=`<input type='text' disabled value="" class="txt txt-md" v-on:click="save('button')" />`;
const tagAttrs=strHtml.match(/(?<=\s)[\w:-]+(=(["']).*?\2)*/g) || [];
console.log(tagAttrs);
//  ["type='text'", 'disabled', 'value=""', 'class="txt txt-md"', `v-on:click="save('button')"`]

匹配结果

可视图

人人为我,我为人人,欢迎您的浏览,我们一起加油吧。

1题. 编写一个Filter,需要()

A. 继承Filter 类

B. 实现Filter 接口

C. 继承HttpFilter 类

D. 实现HttpFilter接口

正确答案为:B


第2题. 自定义标签的配置文件放在________

A. WebRoot

B. lib

C. classes

D. WEB-INF

正确答案为:D


第3题. 有关会话跟踪技术描述正确的是(多选)

A. Cookie是Web服务器发送给客户端的一小段信息,客户端请求时,可以读取该信息发送到服务器端

B. 关闭浏览器意味着会话ID丢失,但所有与原会话关联的会话数据仍保留在服务器上,直至会话过期

C. 在禁用Cookie时可以使用URL重写技术跟踪会话

D. 隐藏表单域将字段添加到HTML表单并在客户端浏览器中显示

正确答案为:ABC


第4题. 在J2EE中,重定向到另一个页面,以下()语句是正确的

A. request . sendRedirect(“http :// www . svse . com . cn”);

B. request . sendRedirect();

C. response . sendRedirect(“http: // www . svse . com . cn”);

D. response .sendRedirect();

正确答案为:C


第5题. EL表达式,${10 mod3},执行结果为:

A. 10 mod 3

B. 1

C. 3

D. null

正确答案为:B


第6题. 自定义标签的作用是

A. 编写和使用方便

B. 规定是这样的,如果不用,别人会说我们不专业

C. 可以减少jsp中的java代码,将代码与界面标签分离,简化前台开发

D. 连数据库

正确答案为:C


第7题. request.getRequestDispatcher().forward(request,response)称之为

A. 流转

B. 转发

C. 重定向

D. 导航

正确答案为:B


第8题. 有关Servlet的生命周期说法正确的有 (多选)

A. Servlet的生命周期由Servlet实例控制

B. init()方法在创建完Servlet实例后对其进行初始化,传递的参数为实现ServletContext接口的对象

C. service()方法响应客户端发出的请求

D. destroy()方法释放Servlet实例

正确答案为:BCD


第9题. 在J2EE中,给定某Servlet的代码如下,编译运行该文件,以下陈述正确的是()。(选择一项)

Public class Servlet1 extends HttpServlet{

Publicvoid init() throws ServletException{

}

Publicvoid service(HttpServletRequest request,HttpServletResponse response)

ThrowsServletException,IOException{

PrintWriterout=response.getWriter();

out.println(“hello!”);

}

}

A. 编译该文件时会提示缺少doGet()或者dopost()方法,编译不能够成功通过

B. 编译后,把Servlet1.class放在正确位置,运行该Servlet,在浏览器中会看到输出文字:hello!

C. 编译后,把Servlet1.class放在正确位置,运行该Servlet,在浏览器中看不到任何输出的文字

D. 编译后,把Servlet1.class放在正确位置,运行该Servlet,在浏览器中会看到运行期错误信息

正确答案为:B


第10题. 在Servlet中,response.getWriter()返回的是____________

A. JspWriter对象

B. PrintWriter对象

C. Out对象

D. ResponseWriter对象

正确答案为:B


第11题. 在web.xml中使用___________标签配置过滤器

A. <filter>和<filter-mapping>

B. <filter-name>和<filter-class>

C. <filter>和<filter-class>

D. <filter-pattern>和<filter>

正确答案为:A


第12题. 自定义标签的描述文件在web.xml中配置正确的

A. <taglib>

<tag-uri>bob-tld</tag-uri>

<tag-location>/WEB-INF/bob.tld</tag-location>

</taglib>

B. <tag>

<taglib-uri>bob-tld</taglib-uri>

<taglib-location>/WEB-INF/bob.tld</taglib-location>

</tag>

C. <jsp-taglib>

<taglib-uri>bob-tld</taglib-uri>

<taglib-location>/WEB-INF/bob.tld</taglib-location>

</jsp-taglib>

D. <jsp-config>

<taglib>

<taglib-uri>bob-tld</taglib-uri>

<taglib-location>/WEB-INF/bob.tld</taglib-location>

</taglib>

</jsp-config>

正确答案为:D


第13题. J2EE中,Servlet API为使用Cookie,提供了()类。

A. javax.servlet.http.Cookie

B. javax.servlet.http.HttpCookie

C. javax.servlet. Cookie

D. javax.servlet.http.HttpCookie

正确答案为:A

码: Lib/html/__init__.py

该模块定义了操作HTML的工具。

  • html.escape(s, quote=True)

将字符串 s 中的字符``&`` 、 < 和 > 转换为安全的HTML序列。 如果需要在 HTML 中显示可能包含此类字符的文本,请使用此选项。 如果可选的标志 quote 为真值,则字符 (") 和 (') 也被转换;这有助于包含在由引号分隔的 HTML 属性中,如 <a href="...">。

  • html.unescape(s)

将字符串 s 中的所有命名和数字字符引用 (例如 >, >, >) 转换为相应的Unicode字符。 此函数使用HTML 5标准为有效和无效字符引用定义的规则,以及 HTML 5 命名字符引用列表。

html 包中的子模块是:

html.parser —— 具有宽松解析模式的HTML / XHTML解析器

html.entities – HTML 实体定义


源代码: Lib/html/parser.py


这个模块定义了一个 HTMLParser 类,为 HTML(超文本标记语言)和 XHTML 文本文件解析提供基础。


class html.parser.HTMLParser(*, convert_charrefs=True)

创建一个能解析无效标记的解析器实例。


如果 convert_charrefs 为 True (默认值),则所有字符引用( script/style 元素中的除外)都会自动转换为相应的 Unicode 字符。


一个 HTMLParser 类的实例用来接受 HTML 数据,并在标记开始、标记结束、文本、注释和其他元素标记出现的时候调用对应的方法。要实现具体的行为,请使用 HTMLParser 的子类并重载其方法。


这个解析器不检查结束标记是否与开始标记匹配,也不会因外层元素完毕而隐式关闭了的元素引发结束标记处理。

HTMLParser 实例有下列方法:


  • HTMLParser.feed(data)

填充一些文本到解析器中。如果包含完整的元素,则被处理;如果数据不完整,将被缓冲直到更多的数据被填充,或者 close() 被调用。data 必须为 str 类型。


  • HTMLParser.close()

如同后面跟着一个文件结束标记一样,强制处理所有缓冲数据。这个方法能被派生类重新定义,用于在输入的末尾定义附加处理,但是重定义的版本应当始终调用基类 HTMLParser 的 close() 方法。


  • HTMLParser.reset()

重置实例。丢失所有未处理的数据。在实例化阶段被隐式调用。


  • HTMLParser.getpos()

返回当前行号和偏移值。


  • HTMLParser.get_starttag_text()

返回最近打开的开始标记中的文本。 结构化处理时通常应该不需要这个,但在处理“已部署”的 HTML 或是在以最小改变来重新生成输入时可能会有用处(例如可以保留属性间的空格等)。


下列方法将在遇到数据或者标记元素的时候被调用。他们需要在子类中重载。基类的实现中没有任何实际操作(除了 handle_startendtag() ):


  • HTMLParser.handle_starttag(tag, attrs)

这个方法在标签开始的时候被调用(例如: <div id="main"> )。


tag 参数是小写的标记名。attrs 参数是一个 (name, value) 形式的列表,包含了所有在标记的 <> 括号中找到的属性。name 转换为小写,value 的引号被去除,字符和实体引用都会被替换。


实例中,对于标签 <A HREF="https://www.cwi.nl/">,这个方法将以下列形式被调用 handle_starttag('a', [('href', 'https://www.cwi.nl/')]) 。


html.entities 中的所有实体引用,会被替换为属性值。


  • HTMLParser.handle_endtag(tag)

此方法被用来处理元素的结束标记(例如: </div> )。


tag 参数是小写的标签名。


  • HTMLParser.handle_startendtag(tag, attrs)

类似于 handle_starttag(), 只是在解析器遇到 XHTML 样式的空标记时被调用( <img ... />)。这个方法能被需要这种特殊词法信息的子类重载;默认实现仅简单调用 handle_starttag() 和 handle_endtag() 。


  • HTMLParser.handle_data(data)

这个方法被用来处理任意数据(例如:文本节点和 <script>...</script> 以及 <style>...</style> 中的内容)。


  • HTMLParser.handle_entityref(name)

这个方法被用于处理 &name; 形式的命名字符引用(例如 >),其中 name 是通用的实体引用(例如: 'gt')。如果 convert_charrefs 为 True,该方法永远不会被调用。


  • HTMLParser.handle_charref(name)

这个方法被用来处理 &#NNN; 和 &#xNNN; 形式的十进制和十六进制字符引用。例如,> 等效的十进制形式为 > ,而十六进制形式为 > ;在这种情况下,方法将收到 '62' 或 'x3E' 。如果 convert_charrefs 为 True ,则该方法永远不会被调用。


  • HTMLParser.handle_comment(data)

这个方法在遇到注释的时候被调用(例如: <!--comment--> )。


例如, <!-- comment --> 这个注释会用 ' comment ' 作为参数调用此方法。


Internet Explorer 条件注释(condcoms)的内容也被发送到这个方法,因此,对于 <!--[if IE 9]>IE9-specific content<![endif]--> ,这个方法将接收到 '[if IE 9]>IE9-specific content<![endif]' 。


  • HTMLParser.handle_decl(decl)

这个方法用来处理 HTML doctype 申明(例如 <!DOCTYPE html> )。


decl 形参为 <!...> 标记中的所有内容(例如: 'DOCTYPE html' )。


  • HTMLParser.handle_pi(data)

此方法在遇到处理指令的时候被调用。data 形参将包含整个处理指令。例如,对于处理指令 <?proc color='red'> ,这个方法将以 handle_pi("proc color='red'") 形式被调用。它旨在被派生类重载;基类实现中无任何实际操作。


注解 HTMLParser 类使用 SGML 语法规则处理指令。使用 '?' 结尾的 XHTML 处理指令将导致 '?' 包含在 data 中。


  • HTMLParser.unknown_decl(data)

当解析器读到无法识别的声明时,此方法被调用。


data 形参为 <![...]> 标记中的所有内容。某些时候对派生类的重载很有用。基类实现中无任何实际操作。

源码: Lib/html/entities.py

该模块定义了四个词典, html5、 name2codepoint、 codepoint2name、以及 entitydefs。


  • html.entities.html5

将 HTML5 命名字符引用 1 映射到等效的 Unicode 字符的字典,例如 html5['gt;']=='>'。 请注意,尾随的分号包含在名称中(例如 'gt;'),但是即使没有分号,一些名称也会被标准接受,在这种情况下,名称出现时带有和不带有 ';'。另见 html.unescape()。


  • html.entities.entitydefs

将 XHTML 1.0 实体定义映射到 ISO Latin-1 中的替换文本的字典。


  • html.entities.name2codepoint

将 HTML 实体名称映射到 Unicode 代码点的字典。


  • html.entities.codepoint2name

将 Unicode 代码点映射到 HTML 实体名称的字典。