我已经研究过stackoverflow并找到了类似的结果,但它并不是我想要的。
在javascript上下文中给出一个xml字符串:"<a b=\"c\"></a>"
,我想创建一个捕获属性值的正则表达式,包括引号。
注意:如果您使用单引号,则类似。
目前我有一个针对XML规范定制的正则表达式:
[_A-Za-z][\w\.\-]*(?:=\"[^\"]*\")?
[_A-Za-z][\w\.\-]* //This will match the attribute name.
(?:=\"[^\"]*\")? //This will match the attribute value.
\"[^\"]*\" //This part concerns me.
我现在的问题是,如果xml字符串如下所示:
<shout statement="Hi! \"Richeve\"."></shout>
我知道这是一个愚蠢的问题,但我只想捕捉这种情况可能发生的罕见情况(我知道编码器可以在这种情况下使用单引号)但有些情况我们不知道当前情况属性值在运行时动态更改的属性值。
所以为了更清楚,使用正确的正则表达式的结果应该是:
"Hi! \"Richeve\"."
我希望我的问题很明确。谢谢你的帮助!
PS:请注意,语言上下文是Javascript,我知道使用lookbehinds很有吸引力,但目前不支持lookbehinds。
PS:我知道解析XML真的很难,但我有一个优雅的解决方案:)所以我只需要解决这个小问题。所以这个问题只是主要关注的是捕获引号中标记的字符串标记,其中包含字符串标记内的引号。
答案 0 :(得分:0)
具有匹配分隔符和嵌入式转义分隔符的内容的标准模式如下:
"[^"\\]*(?:\\.[^"\\]*)*"
忽略模式中明显的第一个和最后一个字符,以下是模式其余部分的工作原理:
[^"\\]*
:使用所有字符,直到分隔符或反斜杠(在示例中匹配Hi!
)
(?:\\.[^"\\]*)*
尝试使用单个转义字符\\.
后跟一系列非分隔符/反斜杠字符(首先匹配\"Richeve
然后再匹配\".
例如)
就是这样。
您可以尝试使用(['"])
和后引用使用更通用的分隔符方法,或者您可以只允许使用单引号的备用模式:
("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')
以下是对此技术的另一种描述,可能也会有所帮助(请参阅“字符串”一节):http://www.regular-expressions.info/examplesprogrammer.html
答案 1 :(得分:0)
我非常确定在双引号属性值中嵌入双引号是不合法的。您可以在值中使用等效于双引号\x22
的unicode。
然而回答这个问题,这个表达式会:
statement
的值 <shout\b(?=\s)(?=(?:[^>=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*?\sstatement=(['"])((?:\\['"]|.)*?)\1(?:\s|\/>|>))(?:[^>=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/shout>
示例文字
注意第一个属性中的困难边缘情况:)
<shout onmouseover=' statement="He said \"I am Inside the onMouseOver\" " ; if ( 6 > a ) { funRotate(statement) } ; ' statement="Hi! \"Richeve\"." title="sometitle">SomeString</shout>
<强>匹配强>
组0从打开到关闭获取整个标签
第1组获取围绕声明属性值的引用,这用于正确匹配结束引用
第2组获取语句属性值,该值可能包含\"
之类的转义引号,但不包括周围的引号
[0][0] = <shout onmouseover=' statement="He said \"I am Inside the onMouseOver\" " ; if ( 6 > a ) { funRotate(statement) } ; ' statement="Hi! \"Richeve\"." title="sometitle">SomeString</shout>
[0][1] = "
[0][2] = Hi! \"Richeve\".