Perl - 用于查找和替换不属于字符实体的&符号的正则表达式

Perl - Regex to find and replace ampersands that aren't part of a character entity

所以我目前使用的代码是:

$mystring =~ s/&/&/g;   

查找并替换我的字符串变量中的所有符号 (&),并将它们替换为符号 (&) 的 XML 实体引用。问题是,我只想替换尚未属于 XML 实体引用的 & 符号。

例如,假设我在此之前进行了查找和替换,使所有“>”成为“>”。

它有一个符号,但我不希望代码的第一位替换它,因为它后面是 #62;

可能不足以排除“&#”,因为数据中合法存在的可能性很小。那么我可以在正则表达式中排除&符号后跟“#__;”的地方吗?

或者,我要排除的具体三个示例是“&#44;”(逗号)、“&#62;”(>)和“&#60;” (<)。这些是我唯一要做的其他查找和替换,所以如果有办法专门排除那些,那也行。

谢谢!

&(?!#\d+;)

此表达式匹配任何后面没有带数字的散列字符的 & 字符。

这里 DEMO 有更多解释。

XML 字符引用的语法定义为

Reference     ::= EntityRef | CharRef
EntityRef     ::= '&' Name ';'
CharRef       ::= '&#' [0-9]+ ';'
                | '&#x' [0-9a-fA-F]+ ';'
Name          ::= NameStartChar (NameChar)*
NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
NameChar      ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]

因此,如果以下内容不是有效引用的一部分,则将对 & 进行转义。

my $name_start_char_class = ':A-Z_a-z\x{00C0}-\x{00D6}\x{00D8}-\x{00F6}\x{00F8}-\x{02FF}\x{0370}-\x{037D}\x{037F}-\x{1FFF}\x{200C}-\x{200D}\x{2070}-\x{218F}\x{2C00}-\x{2FEF}\x{3001}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFFD}\x{10000}-\x{EFFFF}';
my $name_start_char       = qr/[$name_start_char_class]/;
my $name_char             = qr/[${name_start_char_class}\-.0-9\x{00B7}\x{0300}-\x{036F}\x{203F}-\x{2040}]/;
my $name                  = qr/$name_start_char$name_char*/;

s/&(?!(?:$name|#(?:[0-9]+|x[0-9a-fA-F]+));)/&#38;/g

请注意,这假定您的 XML 字符串不包含 CDATA 部分。