Perl - 用于查找和替换不属于字符实体的&符号的正则表达式
Perl - Regex to find and replace ampersands that aren't part of a character entity
所以我目前使用的代码是:
$mystring =~ s/&/&/g;
查找并替换我的字符串变量中的所有符号 (&
),并将它们替换为符号 (&
) 的 XML 实体引用。问题是,我只想替换尚未属于 XML 实体引用的 & 符号。
例如,假设我在此之前进行了查找和替换,使所有“>
”成为“>
”。
它有一个符号,但我不希望代码的第一位替换它,因为它后面是 #62;
。
可能不足以排除“&#
”,因为数据中合法存在的可能性很小。那么我可以在正则表达式中排除&符号后跟“#__;
”的地方吗?
或者,我要排除的具体三个示例是“,
”(逗号)、“>
”(>
)和“<
” (<
)。这些是我唯一要做的其他查找和替换,所以如果有办法专门排除那些,那也行。
谢谢!
&(?!#\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]+));)/&/g
请注意,这假定您的 XML 字符串不包含 CDATA 部分。
所以我目前使用的代码是:
$mystring =~ s/&/&/g;
查找并替换我的字符串变量中的所有符号 (&
),并将它们替换为符号 (&
) 的 XML 实体引用。问题是,我只想替换尚未属于 XML 实体引用的 & 符号。
例如,假设我在此之前进行了查找和替换,使所有“>
”成为“>
”。
它有一个符号,但我不希望代码的第一位替换它,因为它后面是 #62;
。
可能不足以排除“&#
”,因为数据中合法存在的可能性很小。那么我可以在正则表达式中排除&符号后跟“#__;
”的地方吗?
或者,我要排除的具体三个示例是“,
”(逗号)、“>
”(>
)和“<
” (<
)。这些是我唯一要做的其他查找和替换,所以如果有办法专门排除那些,那也行。
谢谢!
&(?!#\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]+));)/&/g
请注意,这假定您的 XML 字符串不包含 CDATA 部分。