【问题标题】:Tricky substring problems棘手的子字符串问题
【发布时间】:2015-12-27 20:18:36
【问题描述】:

我的子字符串有问题,我有一个格式如下的字符串 目前正在使用 getline。

Richard[12345/678910111213141516] was murdered

我一直在使用find_last_offind_first_of 来获取括号和正斜杠之间的位置以检索每个字段。我有这个工作和功能,但我遇到了一个问题。名称字段的长度可以是 32 个字符,并且可以包含 / 和 [],所以当我最终遇到一个用户,其名称的 URL 为用户时,我并不喜欢这样。这些数字在每个用户的基础上也是随机的。我从字符串、名称和两个标识号中检索每个字段。

另一个字符串可能看起来像这样,所以我将抓取总共 6 个子字符串。

Richard[12345/678910111213141516] was murdered by Ralph[54321/161514131211109876]

这只是另一个巨大的混乱,我想做的是从后面开始移动到前面,但是如果第二个名称字段 (Ralph) 包含任何 / 或 [] 它会破坏计数用于检索第一部分。任何见解都会有所帮助。谢谢。

简而言之。我该如何解释这些。

名称还可以包含任何字母/数字和特殊字符。

Richard///[][][12345/678910111213141516] was murdered by Ralph[/[54321/161514131211109876]

最终结果将是包含此的 6 个子字符串。

  • 理查德///[][]
  • 12345
  • 678910111213141516
  • 拉尔夫[/
  • 54321
  • 161514131211109876

我已经提到过正则表达式,但我不知道它是否更适合这项任务,我添加了标签,以便更有经验的人回答/评论。

【问题讨论】:

  • 可怜的 Richard :( - 所以,你想在一个字符串中获取名称,而在另一个字符串中获取 ID?
  • 没有。我可以这样做,但我无法解释人名的随机性,他们的名字可能是 Richard/////[[[[[]][[] 以及我目前正在搜索的方式那些不能解释这一点。我想知道的是我怎么能解释这样的名字。
  • 对不起,我有点不清楚,我会编辑帖子。
  • 名字不能有数字?严格吗?
  • 名称可以包含任何字母/数字和特殊字符,这就是我认为 Regex 行不通的原因。

标签: c++ regex substring getline


【解决方案1】:

这是获取所有值的正则表达式方式:

string str = "Richard///[][][12345/678910111213141516] was murdered by Ralph[/[54321/161514131211109876]";
regex rgx1(R"(([A-Z]\w*\s*\S*)\[(\d+)?(?:\/(\d+))?\])");
smatch smtch;
while (regex_search(str, smtch, rgx1)) {
        std::cout << "Name: " << smtch[1] << std::endl;
        std::cout << "ID1: " << smtch[2] << std::endl;
        std::cout << "ID2: " << smtch[3] << std::endl;
        str = smtch.suffix().str();
    }

IDEONE demo

正则表达式(\S*)\[(\d+)?(?:/(\d+))?\] 匹配:

  • (\S*) -(第 1 组)0 个或多个非空白符号,尽可能多
  • \[ - 左方括号(必须转义,因为它是正则表达式中为字符类保留的特殊字符)
  • (\d+)? - (组 2)1 位或多位(可选组,可以为空)
  • (?:/(\d+))? - 非捕获可选组匹配
    • / - 文字 /
    • (\d+) -(第 3 组)1 个或多个数字。
  • \] - 右方括号。

【讨论】:

  • 是的,这两个答案都有效,但是它们被空白regex101
  • 与一个空格一起使用,如果名称不大写,它也会爆发,我觉得我只是要求你为我做这件事,我尝试使用正则表达式,但老实说没有处理过这么深的事情。
  • 问题是:界限是什么?我们应该从哪里开始匹配,我们应该在哪里停止?一旦你用文字表达出来,我们将能够提供一个可行的答案。按照你说的,我们必须匹配Richard///[][][12345678910111213141516,然后是was murdered by Ralph[/54321161514131211109876
  • 是的,但可变性超出了我的控制,第一部分的名称可以是任何字母数字字符和特殊字符,至少两个字符和任意数量的空格最多 32 个字符,它是用户名在 Steam 上。
【解决方案2】:

一个可能的正则表达式解决方案是使用如下模式:

(\S+)\[(\d+)/(\d+)\](?:\s|$)

它将匹配并存储名称(及其元属性)。我目前正在考虑什么时候它可能会破裂。

你可以测试一下on regex101

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2014-09-10
    相关资源
    最近更新 更多