我正在尝试编写正则表达式来验证XML文件,并在C ++中提取存储在标记之间的字符串。
这是我的目标之一:
"<[^/]*?>"
然而,这不起作用。这样的事情也不简单:
"<[a-z]*>"
但是,这会产生匹配:
"<.*>"
支架似乎不能匹配。
以下是我正在使用的代码的相关部分:
string testString = "<test>";
regex xmlRegOpenTag("<[^/]*?>", regex_constants::extended);
smatch smOpen;
cout << regex_match(testString, smOpen, xmlRegOpenTag) << endl;
string openCap = smOpen[0];
cout << "openCap: " << openCap << endl;
我尝试过使用regex_constants :: basic等其他标志。似乎没什么用。我正在使用gcc 4.7.3版进行编译。
那些提到我不应该使用正则表达式解析XML的人:我只需要解析我自己创建的XML文件,所以这不是问题。
我正在使用C ++ 11标准。在我的头文件中,我包括正则表达式:
#include <regex>
using namespace std;
当使用第一个正则表达式(“&lt; [^ /] *?&gt;”)时,我得到:
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
Abort
当使用第二个正则表达式(“&lt; [a-z] *&gt;”)时,我得到:
0
openCap:
当使用第三个正则表达式(“&lt;。*&gt;”)时,我得到:
1
openCap: <test>
这是我可以提供的有关我正在使用的编译器的信息:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.3-1ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --enable-objc-gc --with-cloog --enable-cloog-backend=ppl --disable-cloog-version-check --disable-ppl-version-check --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
答案 0 :(得分:2)
首先,XML不是常规语言,你不应该尝试使用RegExes来解析它,最终它会给你一些真正的坏头疼,你应该使用一个可用的XML解析器。例如,假设您有"<foo><bar /></foo>"
之类的内容,<.*>
之类的内容将匹配整个字符串,而不仅仅是第一个标记,而是整个字符串。您可以尝试与<.*?>
使用“lazy”匹配,>
尝试匹配尽可能少的字符,但如果您在属性中的字符串中有<test>
,则可能仍会中断。
现在,让我们假装用RegExes解析XML不会有问题:你提供的所有RegExes都应该匹配regex reg("<[^/]*>");
if (regex_match("<test>", reg))
cout << "Matched..." << endl;
else
cout << "Didn't match..." << endl;
并在我尝试的实现中这样做,这表明你的错误您使用的代码或库,但我没有在您的代码中看到一个,并且正则表达式的标准实现也不应该是错误的...
编辑:我刚刚尝试使用C ++,RegExes也可以使用。在极简主义的实施中
<[a-z]*>
产生输出“匹配...” - 并且{{1}}也可以。我在这个过期时使用过clang-500.2.79。这基本上证实了编译器提供的实现是错误的。
答案 1 :(得分:0)
你试过的正则表达式
[^/]*
表示除'/'
之外的任何字符(0次或更多次(匹配尽可能多的数量))
[a-z]*
表示'a'
到'z'
的任何字符(0或更多)
次(匹配尽可能多的数量))
.*
表示任何字符(0次或更多次)
(匹配尽可能多的数量))
答案 2 :(得分:0)
我遇到了同样的问题。看起来字符集匹配(带方括号)在gcc4.x中使用默认的ECMA脚本语法。使用std :: regex:扩展解析器似乎工作。 即
std::regex re(".*", std::regex::ECMAScript); -> ok
std::regex re("[a-z]", std::regex::ECMAScript); -> regex_error
std::regex re("[a-z]", std::regex::extended); -> ok