如何捕获C++正则表达式中的0-2组并打印它们?

2024-03-16

Edit 3

当我陷入正则表达式困境时,我采用了 good'ol 自定义解析方法。事实证明这并没有那么糟糕,因为文件内容可以非常整齐地标记,并且可以使用以下命令在循环中解析标记very简单的状态机。对于那些想要检查的人,在我在 Stackoverflow 中的另一个问题中,有一段代码使用 range-for、ifstream 迭代器和自定义流标记生成器来执行此操作here https://stackoverflow.com/questions/11282437/why-doesnt-range-for-find-my-overloads-of-begin-and-end-for-stdistream-iterat。这些技术大大降低了定制解析器的复杂性。

我想在两个捕获组的第一部分中标记文件内容,然后逐行标记。我想要一个半功能性的解决方案,但我想学习如何让它变得更好。也就是说,没有“额外的处理”来弥补我对捕获组知识的缺乏。接下来是一些预备知识,最后是一个更精确的问题(行

const std::regex expression("([^:]+?)(^:|$)");

...是我想结合处理其结果来询问的问题)。

这些文件基本上定义如下:

definition_literal : value_literal
definition_literal : value_literal
definition_literal : value_literal
definition_literal : value_literal
HOW TO INTERPRET THE FOLLOWING SECTION OF ROWS
[DATA ROW 1]
[DATA ROW 2]
...
[DATA ROW n]

其中每个数据行由一定数量的整数或浮点数组成,并用空格分隔。每行的数字与其他行的数字一样多(例如,每行可以有四个整数)。所以,“解释部分”基本上是在一行中以纯文本形式讲述这种格式。

我有一个几乎可以工作的解决方案,可以读取这样的文件:

int main() 
{
    std::ifstream file("xyz", std::ios_base::in);
    if(file.good())
    {
        std::stringstream file_memory_buffer;
        file_memory_buffer << file.rdbuf();
        std::string str = file_memory_buffer.str(); 
        file.close();

        const std::regex expression("([^:]+?)(^:|$)");
        std::smatch result;

        const std::sregex_token_iterator end;       
        for(std::sregex_token_iterator i(str.begin(), str.end(), expression); i != end; ++i)
        {
            std::cout << (*i) << std::endl;
        }
    }

    return EXIT_SUCCESS;
}

随着正则表达式的定义expression,它现在打印<value>定义文件的部分,然后是解释部分,然后是逐行的数据行。如果我将正则表达式更改为

"([^:]+?)(:|$)"

...它打印以一组为一组标记的所有行,几乎就像我想要的那样,但是如何以两组为一组标记第一部分,然后逐行标记其余部分?

任何指针、代码、解释都受到真正的欢迎。谢谢。

EDIT:

正如所指出的Tom Kerr已经,但还有一些额外的要点,这也是一个排练,或者如果你愿意的话,也可以编码 kata,不是为了编写自定义解析器,而是看看我是否可以 - 或者我们可以:-) - 使用正则表达式来完成此任务。我知道正则表达式不是这里最有效的方法,但这并不重要。

我希望拥有的是类似于标题信息元组列表(大小为 2 的元组),然后是 INTERPRET 行(大小为 1 的元组),我可以用它来选择一个关于如何处理数据的函数行(大小为 1 的元组)。

是的,“如何解释”行包含在一组定义明确的字符串中,我可以从头开始逐行读取,一路分割字符串,直到遇到解释行之一。我知道,这个正则表达式解决方案不是最有效的方法,而更像是编写 kata 代码,让自己编写除客户解析器之外的其他内容(我上次用 C++ 编写已经花了相当长的时间,所以这也是在排练) )。

EDIT 2

我已经设法通过更改迭代器类型来访问元组(在这个问题的上下文中),如下所示

const std::sregex_iterator end;     
for(std::sregex_iterator i(str.begin(), str.end(), expression); i != end; ++i)
{
    std::cout << "0: " << (*i)[0] << std::endl;
    std::cout << "1: " << (*i)[1] << std::endl;
    std::cout << "2: " << (*i)[2] << std::endl;
    std::cout << "***" << std::endl;
}

尽管这距离我想要的还很远,但我尝试使用的正则表达式有问题。无论如何,这个新发现,另一种迭代器,也有帮助。


我相信您正在尝试的是:

TEST(re) {
    static const boost::regex re("^([^:]+) : ([^:]+)$");

    std::string str = "a : b";
    CHECK(boost::regex_match(str, re));
    CHECK(!boost::regex_match("a:a : bbb", re));
    CHECK(!boost::regex_match("aaa : b:b", re));

    boost::smatch what;
    CHECK(boost::regex_match(str, what, re, boost::match_extra));
    CHECK_EQUAL(3, what.size());
    CHECK_EQUAL(str, what[0]);
    CHECK_EQUAL("a", what[1]);
    CHECK_EQUAL("b", what[2]);
}

但我不确定在这种情况下我会推荐正则表达式。我想你会发现一次只读一行,然后继续阅读:,然后修剪空间使其更易于管理。

我想如果你不能依赖下面的行作为哨兵,那么事情会更困难。通常我希望这样的格式从该行中显而易见,而不是标题的每一行的格式。

HOW TO INTERPRET THE FOLLOWING SECTION OF ROWS
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何捕获C++正则表达式中的0-2组并打印它们? 的相关文章

  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • 在 C# 中轻松创建支持索引的属性

    在 C 中我发现索引属性 http msdn microsoft com en us library aa288464 VS 71 aspx非常有用 例如 var myObj new MyClass myObj 42 hello Conso
  • C++ 和序列化:有什么方法可以进行某种内省吗?

    我读过一些例子维基百科 http en wikipedia org wiki Type introspection C 2B 2B但我正在寻找一些现实生活中的例子 如何使用内省 为什么 它有助于编写干净的代码 以及代码本身 例如 有没有办法
  • 比较 LINQ to SQL 中的两个日期

    我有一个数据库 其中有一个名为会议的表 会议日期使用以下格式存储在此表中 May 2nd 2011 例如 格式为5 2 2011 我的要求是获取两个日期 例如 2011 年 4 月 25 日和 2011 年 5 月 2 日 之间的会议 并编
  • 增量决策树 C++ 实现

    有谁知道决策树分类器的增量实现吗 这样 当您将新实例添加到训练集中时 它可以根据现有决策树分类器以低计算量并尽可能快地生成最佳决策树分类器 换句话说 我有一个最优决策树分类器集A 其中命名为T 1 现在我想添加实例X to set A并找到
  • & 运算符的含义是什么?

    在下面的代码中 Expression
  • 通过用于 Symbol 条码扫描仪 DS4208 的 SNAPI.dll API 捕获图像

    我想通过 SNAPI API 从 Symbol 目前为 Zebra 条形码扫描仪 DS4208 型号 我们还使用 Zebra 的另一个但兼容的型号 捕获图像 条形码捕获 识别效果很好 但看起来像SnapiDLL SNAPI SnapShot
  • 我要恢复我的记忆!我怎样才能真正处理一个控件?

    我正在制作一个应用程序 它创建大量的窗口控件 按钮和标签等 它们都是通过函数动态生成的 我遇到的问题是 当我删除控件并处置它们时 它们不会从内存中删除 void loadALoadOfStuff while tabControlToClea
  • 多维数组和指向指针的指针

    创建多维数组时char a 10 10 根据我的书 它说你必须使用类似于char a 10 将数组传递给函数 为什么必须这样指定长度 您不是只是将双指针传递给 with 并且该双指针不是已经指向分配的内存吗 那么为什么参数不能是char a
  • 以编程方式运行 T4 文本模板

    有没有一种方法可以通过代码以编程方式运行 T4 文本模板 我正在制作一种自定义域特定语言 我希望相关的文本模板在用户每次保存时运行 目前 这就是我在 DSL 模型中所做的事情 protected override void OnDocume
  • EF Core 一对多关系列表返回 null

    我正在尝试学习如何在 EF Core 中正确利用 DbContext 我有一个团队课程 public class Team public int ID get set public string Name get set public bo
  • 电子邮件正则表达式将如何处理新的 unicode 域?

    Since 2009年10月 互联网 名称指定公司和 Numbers ICANN 批准了创建 国家 地区代码顶级域名 ccTLD 在互联网上使用 母语 IDNA 标准 脚本 我很确定大多数网站当前使用的标准正则表达式不会将它们标记为有效 还
  • 我可以在 C++ 中重写非虚函数吗

    我想知道我可以重写 C 中的非虚函数吗 因为我在使用 C 时发现了这个问题override关键字我的代码如下 class A public void say cout lt lt From A n class B public A publ
  • 如何使用 ProtoGen 从 proto 文件生成结构

    我们一直在使用 protobuf net ProtoGen 从 proto 文件生成 C cs 文件 我们希望代替类来生成结构 例如 DataContract public struct Entity1 ProtoMember 1 publ
  • C 中的链表数组:初始化和插入?

    我需要创建一个链表数组 如图所示 这就是我到目前为止所做的 typedef struct Node int data struct Node next Node int main void Node link 5 for int q 0 q
  • 类型别名和不完整类型

    我可能已经超出了解决这个本应简单的问题的范围 我在这里开始这个问题 在编译时获取基类的类型 https stackoverflow com questions 17735852 getting type of a base class at
  • 使用 _Alignas 进行结构成员对齐

    我想知道以下问题 是新的吗 Alignas结盟 C11 中的说明符适用于结构成员吗 我一直假设这么多 但彻底阅读了 N1570 公开草案似乎表明对齐说明符不能 出现在一个说明符限定符列表 这就是我所期望的 如果得到支持的话 我已经读过几遍语
  • C# 3.0 中自动属性和公共字段的区别

    我无法理解为什么 C 3 0 中存在自动实现的属性语言功能 当你说的时候有什么区别 public string FirstName than public string FirstName get set 因为它们在生成的 IL 代码 和机
  • char[length]初始化并处理

    我定义了一个字符数组 char d 6 如果我在以下方面有误 请纠正我 此时没有为变量分配内存d 现在我要初始化它 d aaaaa 这种初始化之后 就不需要释放内存了 它将自动完成 我怎么知道是否char 被初始化了吗 我正在寻找类似的模式
  • C#:如何处理乱序 TCP 数据包?

    请有人解释一下如何处理乱序数据包 我使用原始套接字来捕获数据包 并在数据包到来时解析它们 但其中一些数据包的顺序错误 例如 ID 标志 16390 PSH ACK 16535 PSH ACK 16638 确认 16640 PSH ACK 1

随机推荐