2

概括

您可以使用正则表达式匹配多个字符,但用特定替换替换单个字符。

例如,替换\\\、替换"\x22、替换'\x27

据我了解,这根本不可能,因为您可以在表达式中使用捕获的子匹配,但不能使用任何允许您在发生子匹配时有条件地输出文本的逻辑级别。

以下 VB.NET 代码显然是完全不正确的,但让您了解我的想法......(即,如果有一个替换命令允许您说“如果发生子匹配 1,则\\改为输出”)

RegEx.Replace(text, "(\)?("")?(')?", "{if($1,'\\')}{if($2,'\x22')}{if($2,'\x27')}")

(这将与 .NET RegEx 类一起使用,但对于与 javascript RegExp 类一起使用会很有用)

背景

更多是出于兴趣而不是实际需要,但我一直在使用编码文本以在 javascript 参数中使用。(嗯,需求肯定存在,但兴趣在于效率。)

我一直在使用标准String.Replace,并使用以下两个功能对性能进行了一些测试......

Public Function GetJSSafeString(ByVal text As String) As String
    Return text.Replace("\", "\\").Replace("""", "\x22").Replace("'", "\x27")
End Function
Public Function GetJSSafeString2(ByVal text As String) As String
    If text.Contains("\") Then
        text = text.Replace("\", "\\")
    End If
    If text.Contains("""") Then
        text = text.Replace("""", "\x22")
    End If
    If text.Contains("'") Then
        text = text.Replace("'", "\x27")
    End If
    Return text
End Function

使用两个字符串,长度都约为 200 个字符 - 第一个不包含任何要转换的字符 - 第二个包含每个要转换的字符 ( \"')。我通过这两个函数分别运行了这两个字符串 100000 次。

四个结果(以总毫秒为单位)大致为......

GetJSSafeString, no converted characters: 182.0364
GetJSSafeString, converted characters: 316.0632

GetJSSafeString2, no converted characters: 60.012
GetJSSafeString2, converted characters: 354.0708

所以很明显 GetJSSafeString2 如果没有替换是最好的,如果有要转换的字符则最差(但不会更糟,所以看起来是更好的选择)。

但这让我想到......这可以用一个正则表达式来完成吗?

如果是这样,它会比上述两个函数中的任何一个更快吗?

4

2 回答 2

2

JavaScript 中的解决方案:

var text="this is a test \\ with \"things\" to ' replace";
var h={'\\':'\\\\', '"':"\\x22", "'":"\\x27"}; //we define here the replacements
text=text.replace(/("|\\|')/g,function(match){return h[match]});
alert(text); //prints: this is a test \\ with \x22things\x22 to \x27 replace
于 2013-10-03T10:36:44.137 回答
1

非常感谢@psxls 的回答,这对未来的 javascript 实现很有用。

他的回答让我看到了 .NET RegEx.Replace 函数的重载(老实说,我一开始就应该这样做,我的错)......并且有一个 MatchEvaluator 委托。

所以我已经实现了以下代码作为测试(以补充我的答案中已经存在的代码)......

Public Function GetJSSafeString3(ByVal text As String) As String
    Return Regex.Replace(text, "(\\|""|')", New MatchEvaluator(AddressOf GetJSSafeString3Eval))
End Function
Public Function GetJSSafeString3Eval(ByVal textMatch As Match) As String
    Select Case textMatch.Value
        Case "\"
            Return "\\"
        Case """"
            Return "\x22"
        Case "'"
            Return "\x27"
    End Select
    Return ""
End Function

结果和我预期的一样……这比我原来的问题函数中的任何一个函数效率都要低得多(以下以毫秒为单位)

GetJSSafeString, no converted characters: 182
GetJSSafeString, converted characters: 316

GetJSSafeString2, no converted characters: 60
GetJSSafeString2, converted characters: 354

GetJSSafeString3, no converted characters: 477
GetJSSafeString3, converted characters: 856

由于我将要转换的大多数字符串不包含任何提到的字符,因此我正在实现 GetJSSafeString* 2 * 函数,因为这对于大多数情况来说是迄今为止最有效的。

于 2013-10-03T12:21:35.447 回答