我需要更改其他人的一些html标签。
例如,我想更改
<EM></EM>
标记为
<strong></strong>
标签,除了
中的单词<EM>
标签是等,即:
<EM>et al</EM>.
有没有一种方法可以使用单个替换操作来匹配开始和结束标记内的EM字
<> </>
或唯一的方法是使用2次替换操作,例如
"(<EM>)(?!et al)", "<strong>"
修改
我在MSAccess中使用VBA。
这是我的UDF:
'--------------------------------------------------------------------
' Name: RegExpReplace
' Purpose: Replace text in a string using Regular Expressions.
' Requires: Microsoft VBScript Regular Expressions 5.5
' Author: Diego F.Pereira-Perdomo
' Date: Dec-27-2012
'--------------------------------------------------------------------
Public Function RegExpReplace(ByVal strInput As String, _
ByVal strPattern As String, _
ByVal strReplace As String, _
Optional booIgnCase As Boolean = False, _
Optional booGlobal As Boolean = True) As String
Dim oRegExp As RegExp
Dim strOutp As String
Set oRegExp = New RegExp
With oRegExp
.IgnoreCase = booIgnCase
.Global = booGlobal
.pattern = strPattern
strOutp = .Replace(strInput, strReplace)
RegExpReplace = strOutp
End With
Set oRegExp = Nothing
End Function
答案 0 :(得分:2)
编辑:
在对VBScript(和VBScript语法)的正则表达式功能进行一些研究之后,最简单的方法似乎是:
Dim re: Set re = New RegExp
re.Pattern = "<em([^>]*)>(?!carmen</em>)([\s\S]*?)</em>"
re.Global = True
re.IgnoreCase = True
Dim str: str = "<em class=""truc"">where</em> in the <eM>world</em> is <em>carmen</em> sandiego?"
Dim rep: rep = "<strong$1>$2</strong>"
MsgBox re.Replace(str, rep)
模式描述:
<em # literal: <em
([^>]*) # capture group 1: all characters except > zero or more times
> # literal: >
(?!carmen</em>) # lookahead assertion: not followed by "carmen</em>"
( # capture group 2:
[\s\S] # all that is a white character + all that is not a white character
# = all possible characters (including newlines)
*? # repeat zero or more times (lazy)
) # close capture group 2
</em> # literal: </em>
该模式旨在完全排除“卡门”。如果要排除包含“carmen”的子字符串,则必须对模式进行一些更改,并注意不要检查标记之外的单词(<em>blah blah blah</em> carmen
)
最简单的方法:
<em([^>]*)>((?:(?!carmen)[\s\S])*?)</em>
请注意,这种方式特别低效,因为正则表达式引擎必须检查每个字符的(?!carmen)
。
另一种方式:
<em([^>]*)>((?:[^<c]+|c(?!armen)|<(?!/em>))*)</em>
这种模式似乎是一个好主意,但存在问题。当字符串包含结束标记</em>
时,一切正常,但如果缺少结束标记,则脚本将因灾难性回溯而崩溃。您可以找到有关此here的更多信息
解决问题的一种方法是使用atomic group (?>..)
(其中不允许正则表达式引擎回溯)代替非捕获组(?:..)
,但使用VBS正则表达式(如Javascript)没有此功能。
但是,您可以使用前瞻,捕获组和反向引用来模拟此功能:(?=(pattern))\1
等同于(?>pattern)
。 (因为前瞻是天生的原子)
如果我用这个技巧重写先例模式,我会得到:
<em([^>]*)>((?:(?=([^<c]+|c(?!armen)|<(?!/em>)))\3)*)</em>
答案 1 :(得分:0)
此表达式非常完美。
<(em)>((?!.*?et al).*?)</\1>
所以基本上它捕获了
(em)
在结束标记中使用它
</\1>
即使之前有字符,也会排除字符串
(?!.*?et al)
或之后
(?!.*?et al).*?
并捕获结果
((?!.*?et al).*?)
嗯,它的作用越多越好:)
使用我的功能替换这些是一些例子:
实施例1,:
?RegExpReplace("<em>et al</em>", _
"<(em)>((?!.*?et al).*?)</\1>", _
"<strong>$2</strong>", _
True)
结果:
<em>et al</em>
例2:
?RegExpReplace("<em>et al </em>", _
"<(em)>((?!.*?et al).*?)</\1>", _
"<strong>$2</strong>", _
True)
结果:
<em>et al </em>
例3:
?RegExpReplace("<em> et al</em>", _
"<(em)>((?!.*?et al).*?)</\1>", _
"<strong>$2</strong>", _
True)
结果:
<em> et al</em>
Ex.4
?RegExpReplace("<em>et a</em>", _
"<(em)>((?!.*?et al).*?)</\1>", _
"<strong>$2</strong>", _
True)
结果
<strong>et a</strong>
Ex.5
?RegExpReplace("<em>t al</em>", _
"<(em)>((?!.*?et al).*?)</\1>", _
"<strong>$2</strong>", _
True)
结果:
<strong>t al</strong>
请注意在搜索模式和替换字符串中使用反向引用。在搜索模式中,必须使用反斜杠和参考编号;在替换字符串中,必须使用美元符号和参考号。
最后,我不同意RegExp对编辑html(文档或字符串)没有用处或更危险的概念。
使用DOM可以很容易地解析html,毫无疑问,这是推荐的工具。
所以我使用DOM来解析Html,提取不同的部分和RegExp来修改细节。
希望这有助于他人。
此致
迭