我一直在尝试一些看似相当简单的事情......起初。
我正在尝试使用正则表达式转换我一直在使用strstr进行的文本操作,这似乎是现在使用c ++ 11的方法。这是一个测试案例:
<!Sometag>
// Lots of code here! (Multiline)
<Sometag!>
<!Sometag2>
// Lots of code here! (Multiline)
<Sometag2!>
编辑:一个更明确的例子。
/// Comments.
<!Vertex>
#version 150
/// code here!
void main()
{
/// code here!
}
<Vertex!>
/// Comments.
<!Fragment>
#version 150
/// code here!
void main()
{
/// code here!
}
<Fragment!>
编辑2:这是一个需要工作的更好的例子:
我已经做了很多组合,但最让人想到的是这一个:
std::smatch u;
std::string s = shader->GetData();
std::regex_match(s, u, std::regex("<.*>(.*)<!.*>"));
我还没有运气,我想知道是否有人会对语法可能有什么想法?!
THX
答案 0 :(得分:0)
如果您的代码很整洁,可以尝试这样的代码:,
需要相应地转义为C,当然:(?:<[^<>!]*?>\n?)((.|\n)*?)(?:<!.*>(\n|$)?)
代码本身就是捕获组$ 1
https://regex101.com/r/vC5xD3/2(这是php,但想法仍然存在)。
答案 1 :(得分:0)
请考虑使用regex_search。然后,您可以访问每个子匹配。以下是您可以从...开始的示例...
std::smatch u;
std::string s = "<Sometag>\n// Lots of code here! (Multiline)\n<!Sometag>\n\n<Sometag2>\n// Lots of code here! (Multiline)\n<!Sometag2>\n";
std::regex e("<[^>]*>([^<]*)<[!][^>]*>[^<]*");
std::cmatch m;
while (s.length() > 0)
{
bool result = std::regex_search(s.cbegin(), s.cend(), u, e);
if (result == false)
break;
for (std::smatch::iterator it = u.begin(); it != u.end(); ++it)
{
std::cout << *it << std::endl;
}
s = u.suffix();
}
修改的 以下表达式更能容忍&lt;在代码中。
std::regex e("^<([^>]*)>(((.|\\n)*)<[!]\\1>[^<]*)?");
这种方式有更多的子匹配,但其中一个是标签之间的内容。
编辑2 根据您提供的更好的示例字符串,这是另一个将目标字符串分解为子匹配的代码示例。第四个子匹配是标签的实际内容
std::smatch u;
std::string s = "/// Comments.\r\n\r\n<!Vertex>\r\n#version 150\r\n\r\n//#define DISPLAY_DIFFUSE 0\r\n//#define DISPLAY_BUMP 1\r\n//#define DISPLAY_SPECULAR 2\r\n//#define ... \r\n\r\n<Vertex!>\r\n\r\n/// Comments.\r\n\r\n<!Fragment>\r\n#version 150\r\n\r\n//#define DISPLAY_DIFFUSE 0\r\n//#define DISPLAY_BUMP 1\r\n//#define DISPLAY_SPECULAR 2\r\n//#define ... \r\n\r\n<Fragment!>\r\n\r\n";
std::regex e("<[!]([^>]*)>"); //to skip to the first tag
std::cmatch m;
// search to the first tag
bool result = std::regex_search(s.cbegin(), s.cend(), u, e);
if (result == true)
{ // skip characters before first tag
s = s.substr(u.prefix().length());
// regex to find <!tag>...<tag!>... capturing several things
// fourth sub-string is the content between the tags
e = std::regex("^<[!]([^>]*)>(((.|[\\n\\r])*)<\\1[!]>[^<]*)");
while (s.length() > 0)
{
// find a tag and its contents
result = std::regex_search(s.cbegin(), s.cend(), u, e);
if (result == false)
break;
// interate through the sub-matches (the 4th is the
// contents between tags
int idx = 0;
for (std::smatch::iterator it = u.begin(); it != u.end(); ++it)
{
if(++idx == 4)
std::cout << *it << std::endl;
}
s = u.suffix();
}
}