1。在没有空格的属性值上添加缺少的结束引号
问题首先是关于纠正无效的 XML 块
<table pgwide="0" id="dvr_config_firmware>
<title>DFR Firmware</title>
<tgroup cols="2">
<colspec colname="col1>
<colspec colname="col2">
到有效的 XML 块
<table pgwide="0" id="dvr_config_firmware">
<title>DFR Firmware</title>
<tgroup cols="2">
<colspec colname="col1">
<colspec colname="col2">
UltraEdit for Windows 版本 28.20.0.70 和 UEStudio 版本 21.10.0.24 是当前使用 Boost 库的 Perl 正则表达式引擎的最新版本。
sln’s answer 中建议的 Perl 兼容正则搜索表达式是:
=(?|(")([^"<>\s]*)()(?=[\s>]|\/>)|(?!")()([^"<>\s]*)("))
它使用 UE v28.20.0.70 和 UES v21.10.0.24 以及其他一些不太旧的旧版本作为替换字符串 ="$2" 产生正确的结果。
具有搜索表达式的 Python 兼容变体
=(?:(")([^"<>\s]*)()(?=[\s>]|\/>)|(?!")()([^"<>\s]*)("))
与sln 建议的替换字符串="\2\5" 一起使用也适用于当前最新版本和以前版本的UE/UES 示例数据。
2。在带有空格的属性值上添加缺少的结束引号
JennyP 在评论中写道,XML 文件还可以包含一个属性值,其中包含缺少结束引号的空格,就像在这个 XML 示例块中一样:
<table pgwide="0" id="dvr_config_firmware>
<title>DFR Firmware</title>
<tgroup cols="2">
<colspec colname="col1>
<colspec colname="col2">
<info date="09 JAN 2000 version="1.0">
现在的预期结果是:
<table pgwide="0" id="dvr_config_firmware">
<title>DFR Firmware</title>
<tgroup cols="2">
<colspec colname="col1">
<colspec colname="col2">
<info date="09 JAN 2000" version="1.0">
但是 sln 建议的 Perl 语法中的前两个正则表达式产生:
<table pgwide="0" id="dvr_config_firmware">
<title>DFR Firmware</title>
<tgroup cols="2">
<colspec colname="col1">
<colspec colname="col2">
<info date="09" JAN 2000 version="1.0">
" 中只包含日期中的某天,而不是整个日期,因为这两个正则表达式不是为具有一个或多个空格的属性值设计的,因为最初没有要求。
sln 建议的 Perl 兼容解决方案是使用搜索表达式
=(?|(")((?:(?![a-z]*=)[^"<>])*)()(?=[\s>]|/>)|(?!")()((?:(?![a-z]*=)[^"<>])*)("))
和="\2" 作为替换表达式字符串,这会导致在预期结果上使用 UE/UES 执行。
使用 Python 兼容的搜索表达式结果也是正确的
=(?:(")((?:(?![a-z]*=)[^"<>])*)()(?=[\s>]|/>)|(?!")()((?:(?![a-z]*=)[^"<>])*)("))
使用替换字符串="\2\5"。
@sln,干得好!
3。在带有空格的属性值上添加缺少的引号
与此同时,UltraEdit 论坛主题Regular expression to search for attributes with missing a quote 也讨论了相同的任务。
我在 UltraEdit 论坛上发布了一个更错误的 XML 块的回复:
<table pgwide=0" id="dvr_config_firmware>
<title>DFR Firmware</title>
<tgroup cols="3">
<colspec colname=col1>
<colspec colname="col2">
<colspec colname="col3 attrib="xyz">
<applicdef verdate="18 Jan 2019 verstatus="ver">
第一个属性pgwide 错过了开头的引号。属性值col1 根本没有用引号引起来。属性值 col3 错过了结束引号,接下来还有一个属性,最后一个 XML 元素也是这种情况,其属性值带有空格和缺少结束引号。
预期的 XML 块是:
<table pgwide="0" id="dvr_config_firmware">
<title>DFR Firmware</title>
<tgroup cols="3">
<colspec colname="col1">
<colspec colname="col2">
<colspec colname="col3" attrib="xyz">
<applicdef verdate="18 Jan 2019" verstatus="ver">
第二章中 sln 建议的 Perl 和 Python 兼容表达式可以很好地为那些在开头或结尾缺少一个的属性值添加引号。但是属性值col1 没有用引号括起来。这当然不是任务的要求。
我建议使用两个 Perl 兼容的正则表达式替换来获得预期的结果:
- 使用
\w=\K([^"=>]+)(?=>) 搜索并使用"$1" 或"\1" 作为替换字符串,将这些属性值括在引号中,同时缺少两个引号,例如col1。
- 使用
\w=\K(?:(?!")|"[^">]*\K(?=>)|"[^ >"]++(?= \w+=)\K|"(?:[^ >"]++(?![>"])(?! \w+=) )+[^ ">]+\K) 搜索并仅使用 " 在仅缺少一个引号的属性值的开头或结尾插入缺少的引号。
UltraEdit 论坛成员 Fleggy 发布了另一个解决方案,它使用条件 Perl 兼容正则表达式和搜索字符串 \w=\K(")?([\w ]+)(?(1)(?!")|"?)(?!\w*[="]) 并替换字符串 "\2",这也适用于 Notepad++。
4。在带有空格的属性值上添加安全缺失的引号
上面写的所有正则表达式都有一个问题:
他们还可以修改用引号括起来的属性值。
示例:XML 块已经是:
<table pgwide="0" id="dvr_config_firmware">
<title>DFR Firmware</title>
<tgroup cols="3">
<colspec colname="col1">
<colspec colname="col2">
<colspec colname="col3" attrib="xyz">
<applicdef verdate="18 Jan 2019" verstatus="ver">
正则表达式替换的使用不应导致对该块的任何修改。但是上面的正则表达式都没有替换在这个块上执行。属性值18 Jan 2019 会导致插入另一个",这使得 XML 块对 XML 解析器无效。
但是感谢Fleggy,还有一种解决方案可以在属性值上添加安全缺失的引号,这些属性值可以有空格,并且在开头或结尾或两边都缺少引号而正确引用的属性值不会以任何方式修改。
此任务的最终 Perl 兼容正则搜索表达式是:
\w=\K(")?([\w ]+)(?(1)(?(?=")(*SKIP)(*FAIL))|"?)(?!\w*=)
替换表达式字符串为:"\2"
谢谢你,Fleggy。