正则习点 --- 11

4.4. Backtracking

NFA引擎最重要的性质是,他会依次处理各个子表达式或组成元素,遇到需要在两个可能成功的可能中进行选择的时候,他会选择其一,同时记住另一个,以备稍后可能的需要。

4.4.1. A Recally Crummy Analogy

Backtracking is like leaving a pile ofbread crumbs at every fork in the road.(回溯就像是在道路的每个分岔口留下一小堆面包屑)

4.4.1.1. A crummy little example

用正则表达式「to(nite|knight|night)」匹配字符串’hot·tonic·tonight!’。第一个元素「t」从字符串的最左端开始尝试,因为无法匹配’h’,所以在这个位置匹配失败。传动装置于是驱动引擎向后移动,从第二个位置开始匹配(同样也会失败),然后是第三个。这时候「t」能够匹配,接下来的「o」无法匹配,因为字符串中对应位置是一个空格。至此,本轮尝试宣告失败。

继续下去,从…tonic…开始的尝试则很有意思。to匹配成功之后,剩下的3个多选分支都成为可能。引擎选取其中之一进行尝试,留下其他的备用(也就是洒下一些面包屑)。在讨论中,我们假定引擎首先选择的是「nite」。这个表达式被分解为“「n」+「i」+「t」+「e」”,在…tonic…遭遇失败。但此时的情况与之前不同,这种失败并不意味着整个表达式匹配失败—因为仍然存在没有尝试过的多选分支(就好像是,我们仍然可以找到先前留下的面包屑)。假设引擎然后选择「knight」,那么马上就会就会遭遇失败,因为「k」不能匹配‘n’。现在只剩下最后的选项「night」,但他不能失败。因为「night」是最后尝试的选项,它的失败也就意味着整个表达式在…tonic…的位置匹配失败,所以传动机构会驱动引擎继续前进。直到引擎开始从…tonight!…处开始匹配,情况又变得有趣了。这一次,多选分支「night」终于可以匹配字符串的结尾部分了(于是整体匹配成功,现在引擎可以报告匹配成功了)。

4.4.2. Two Important Points onBacktracking

²In situations where thedecision is between “make an attempt” and “skip an attempt,” as with itemsgoverned by quantifiers, the engine always chooses to first make the attemptfor greedy quantifiers, and to first skip the attempt for lazy(non-greedy) ones.

如果需要在“进行尝试”和“跳过尝试”之间选择,对于匹配优先量词,引擎会优先选择“进行尝试”,而对于忽略优先量词,会选择“跳过尝试”。

The most recently saved option is the onereturned to when a local failure forces backtracking. They’re used LIFO(last infirst out).

距离当前最近储存的选项就是当本地失败强制回溯时返回的。使用的原则是LIFO。

4.4.3 Saved States

用NFA正则表达式的术语来说,那些面包屑相当于“备用状态(savedstate)”。

A state indicates where matching canrestart from, if need be. It reflects both the position in the regex and thepoint in the string where an untried option begins.

他们用来标记:在需要的时候,匹配可以从这里重新开始尝试。他们保存了两个位置:正则表达式中的位置,和未尝试的分支在字符串中的位置。

4.4.3.1. A match without backtracking

用「ab?c」匹配abc。

「a」匹配之后,匹配的当前状态如下:

‘abc’

「ab?c」

现在该到「b?」了,正则引擎需要决定:是需要尝试「b」呢,还是跳过?因为「?」是匹配优先的,它会尝试匹配。但是,为了确保在这个尝试最终失败之后能够恢复,引擎会把:

‘abc’

「ab?c」

添加到备用状态序列中。也就是说,稍后引擎可以从下面的位置继续匹配:从正则表达式中的「b?」之后,字符串的b之前(也就是当前的位置)匹配。这实际上就是跳过「b」的匹配,而问号容许这样做。

引擎放下面包屑(SavedState)之后,就会继续向前,检查「b」。在示例文本中,他能够匹配,所以新的当前状态变为:

‘abc’

「ab?c」

最终的「c」也能成功匹配,所以整个匹配完成。备用状态不再需要了,所以不再保存它们。

4.4.3.2. A match after backtracking

如果需要匹配的文本是‘ac’,在尝试「b」之前,一切都与之前的过程相同。显然,这次「b」无法匹配。也就是说,对「…?」进行尝试的路走不通。因为有一个备用状态,这个“局部匹配失败”并不会导致整体匹配失败。引擎会进行回溯,也就是说,把“当前状态”切换为最近保存的状态。在本例中,情况就是:

‘ac’

「ab?c」

在「b」尝试之前保存的尚未尝试的选项。这时候,「c」可以匹配“c”,所以整个匹配宣告完成。

4.4.3.3. A non-match

现在,我们用同样的表达式匹配‘abX’。在尝试「b」以前,因为存在问号,保存了这个备用状态:

‘abX’

「ab?c」

「b」能够匹配,但这条路往下却走不通了,因为「c」无法匹配X。于是引擎会回溯到之前的状态,“交还”b给「c」来匹配。显然,这次测试也失败了。如果还有其他保存的状态,回溯会继续进行,但是此时不存在其他状态,在字符串中当前位置开始的整个匹配也就宣告失败。

事情到此结束了吗?没有。传动装置会继续“在字符串中前行,再次尝试正则表达式”,这可能被想象为一个伪回溯(pseudo-backtrack)。匹配重新开始于:

‘abX’

ab?c」

从这里重新开始整个匹配,如同之前一样,所有的道路都走不通。接下来的两次(从“abX”到“abX”)都告失败,所以最终会报告匹配失败。

4.4.3.4. A lazy match

现在来看最开始的例子,使用忽略优先匹配量词,用「ab??c」来匹配‘abc’。「a」匹配之后的状态如下:

‘abc’

「ab??c」

接下来轮到「b??」,引擎需要进行选择:尝试匹配「b」,还是忽略?因为“??”是忽略优先的,它会首先尝试忽略,但是,为了能够从失败的分支中恢复,引擎会保存下面的状态:

‘abc’

「abc」

到备用状态列表中。于是,引擎稍后能够用正则表达式中的「b」来尝试匹配文本中的“b”(我们知道这能够匹配,但是正则引擎不知道,他甚至都不知道是否会要用到这个备用状态)。状态保存之后,他会继续向前,沿着忽略匹配的路走下去:

‘abc’

「ab?? c」

「c」无法匹配‘b’,所以引擎必须回溯到之前保存的状态:

‘abc’

「abc」

显然,此时匹配可以成功,接下来的「c」匹配‘c’。于是我们得到了与使用匹配优先的「ab?c」同样的结果,虽然两者所走的路不相同。

4.4.4. Backtracking andGreediness

4.4.4.1. Star, plus, and their backtracking

如果认为「x*」基本等同于「x?x?x?x?x?x?…」(或者更确切地说「(x(x(x(x…?)?)?)?)」),那么情况与之前没有大的差别。每次测试星号作用的元素之前,引擎都会保存一个状态,这样,如果测试失败(或者测试进行下去遭遇失败),还能够从保存的状态开始匹配。这个过程会不断重复,直到包含星号的尝试完全失败为止。

所以,如果用「[0-9]+」来匹配‘a·1234·num’,「[0-9]」遇到4之后的空格无法匹配,而此时加号能够回溯的位置对应了四个保存的状态:

a 1234num

a 1234 num

a 1234 num

a 1234 num

也就是说,在每个位置,「[0-9]」的尝试都代表一种可能。在「[0-9]」遇到空格匹配失败时,引擎回溯到最近保存的状态(也就是最下面的位置),选择正则表达式中的「[0-9]+」和文本中的‘a·1234·num’。当然,到此整个正则表达式已经结束,所以我们知道,整个匹配宣告完成。

4.4.4.2. Revisiting a fuller example

以正则表达式「^.*([0-9][0-9])」匹配‘CA·95472·USA’为例,在「.*」成功匹配到字符串的末尾时,星号约束的点号匹配了13个字符,同时保存了许多备用状态。

现在我们已经到了字符串的末尾,并把控制权交给第一个「[0-9]」,显然这里的匹配不能成功。没有问题,我们可以选择一个保存的状态来进行尝试(实际上保存了许多的状态)。现在回溯开始,把当前状态设置为最近保存的状态,也就是「.*」匹配最后的A之前的状态。忽略(或者,如果你愿意,可以使用“交还”(unmatching))这个匹配,于是有机会用「[0-9]」匹配这个A,但这同样会失败。

这种“回溯-尝试”(backtrack-and-test)的过程会不断循环,直到引擎交还“2”为止,在这里,第一个「[0-9]」可以匹配。但是第二个「[0-9]」仍然无法匹配,所以必须继续回溯。现在,之前尝试中第一个「[0-9]」是否匹配与本次尝试并无关系了,回溯机制会把当前的状态中正则表达式内的对应位置设置到第一个「[0-9]」以前。我们看到,当前的回溯同样会把字符串中的位置设置到‘7’以前,所以第一个「[0-9]」可以匹配,而第二个「[0-9]」也可以(匹配‘2’)。所以,我们得到一个匹配结果‘CA·95472 USA’,$1得到‘72’。

需要注意的是:第一,回溯机制不但需要重新计算正则表达式和文本的对应位置,也需要维护小括号内的字表达式所匹配文本的状态。在匹配过程中,每次回溯都把当前状态中正则表达式的对应位置指向小括号之前,也就是「^.*([0-9][0-9])」。

最后需要注意的一点:由星号(或其他任何匹配优先量词)限定的部分不受后面元素影响,而只是匹配尽可能多的内容。

资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 无锡平芯微半导体科技有限公司生产的A1SHB三极管(全称PW2301A)是一款P沟道增强型MOSFET,具备低内阻、高重复雪崩耐受能力以及高效电源切换设计等优势。其技术规格如下:最大漏源电压(VDS)为-20V,最大连续漏极电流(ID)为-3A,可在此条件下稳定工作;栅源电压(VGS)最大值为±12V,能承受正反向电压;脉冲漏极电流(IDM)可达-10A,适合处理短暂高电流脉冲;最大功率耗散(PD)为1W,可防止器件过热。A1SHB采用3引脚SOT23-3封装,小型化设计利于空间受限的应用场景。热特性方面,结到环境的热阻(RθJA)为125℃/W,即每增加1W功率损耗,结温上升125℃,提示设计电路时需考虑散热。 A1SHB的电气性能出色,开关特性优异。开关测试电路及波形图(图1、图2)展示了不同条件下的开关性能,包括开关上升时间(tr)、下降时间(tf)、开启时间(ton)和关闭时间(toff),这些参数对评估MOSFET在高频开关应用中的效率至关重要。图4呈现了漏极电流(ID)与漏源电压(VDS)的关系,图5描绘了输出特性曲线,反映不同栅源电压下漏极电流的变化。图6至图10进一步揭示性能特征:转移特性(图7)显示栅极电压(Vgs)对漏极电流的影响;漏源开态电阻(RDS(ON))随Vgs变化的曲线(图8、图9)展现不同控制电压下的阻抗;图10可能涉及电容特性,对开关操作的响应速度和稳定性有重要影响。 A1SHB三极管(PW2301A)是高性能P沟道MOSFET,适用于低内阻、高效率电源切换及其他多种应用。用户在设计电路时,需充分考虑其电气参数、封装尺寸及热管理,以确保器件的可靠性和长期稳定性。无锡平芯微半导体科技有限公司提供的技术支持和代理商服务,可为用户在产品选型和应用过程中提供有
资源下载链接为: https://pan.quark.cn/s/9648a1f24758 在 JavaScript 中实现击展开与隐藏效果是一种非常实用的交互设计,它能够有效提升用户界面的动态性和用户体验。本文将详细阐述如何通过 JavaScript 实现这种功能,并提供一个完整的代码示例。为了实现这一功能,我们需要掌握基础的 HTML 和 CSS 知识,以便构建基本的页面结构和样式。 在这个示例中,我们有一个按钮和一个提示框(prompt)。默认情况下,提示框是隐藏的。当用户击按钮时,提示框会显示出来;再次击按钮时,提示框则会隐藏。以下是 HTML 部分的代码: 接下来是 CSS 部分。我们通过设置提示框的 display 属性为 none 来实现默认隐藏的效果: 最后,我们使用 JavaScript 来处理击事件。我们利用事件监听机制,监听按钮的击事件,并通过动态改变提示框的 display 属性来实现展开和隐藏的效果。以下是 JavaScript 部分的代码: 为了进一步增强用户体验,我们还添加了一个关闭按钮(closePrompt),用户可以通过击该按钮来关闭提示框。以下是关闭按钮的 JavaScript 实现: 通过以上代码,我们就完成了击展开隐藏效果的实现。这个简单的交互可以通过添加 CSS 动画效果(如渐显渐隐等)来进一步提升用户体验。此外,这个基本原理还可以扩展到其他类似的交互场景,例如折叠面板、下拉菜单等。 总结来说,JavaScript 实现击展开隐藏效果主要涉及 HTML 元素的布局、CSS 的样式控制以及 JavaScript 的事件处理。通过监听击事件并动态改变元素的样式,可以实现丰富的交互功能。在实际开发中,可以结合现代前端框架(如 React 或 Vue 等),将这些交互封装成组件,从而提高代码的复用性和维护性。
一、AutoCAD 2016的工作界面 组成要素:由应用程序菜单、标题栏、快速访问工具栏、菜单栏、功能区、命令窗口、绘图窗口和状态栏组成。 1. 切换至AutoCAD 2016 1)工作空间 模式类型:提供草图与注释、三维基础、三维建模三种工作空间模式 二维绘图功能:在草图与注释空间中可使用默认、插入、注释、参数化、视图管理等选项卡进行二维图形绘制 切换方法: 快速访问工具栏→工作空间按钮下拉列表 状态栏→切换工作空间按钮下拉列表 三维功能:三维基础空间包含可视化、坐标、长方体等三维建模工具 2)应用程序菜单 位置:位于界面左上角 核心功能: 搜索命令 文件操作(新建/打开/保存/另存为/输出/发布/打印/关闭) 最近文档管理(可按日期/大小/类型排序) 选项设置(打开选项对话框) 3)标题栏 显示内容:当前程序名称(Autodesk AutoCAD 2016)和文件名称 信息中心功能: 帮助搜索 Autodesk账户登录 软件更新检查 窗口控制(最小化/最大化/关闭) 4)菜单栏 显示设置:通过自定义快速访问工具栏→显示菜单栏选项启用 菜单结构:包含文件、编辑、视图、插入等11个主菜单项 命令示例: 绘图→直线:进入直线绘制模式 绘图→圆弧:提供三、起-圆心-11种绘制方式 5)选项卡和面板 组织结构: 选项卡(默认/插入/注释等) 面板(绘图/修改/注释等) 命令按钮(直线/多段线/圆等) 操作流程:单击命令按钮→绘图区操作→Enter键确认 6)工具栏 调用方式:工具→工具栏→AutoCAD→选择所需工具栏 控制方法: 显示:勾选对应工具栏选项 隐藏:取消勾选或击工具栏关闭按钮 示例操作:绘图工具栏包含直线、构造线等绘图工具按钮 7)绘图窗口 主要功能:核心绘图工作区域 导航控制: 滚动条调整视图 模型/布局空间切换 显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值