【问题标题】:Regular Expression with specific condition具有特定条件的正则表达式
【发布时间】:2016-12-01 12:22:22
【问题描述】:

假设我想创建一个正则表达式来搜索字符串中的两个单词,但条件是它仅在我要查找的两个单词之间没有其他单词之一时才匹配它们。例如:

string input {"Somebody has typed in some words here."}

我正在寻找单词 someone 和 words,但我只希望正则表达式匹配它们,如果它们之间的某处没有键入的单词(typed 只是我不想的几个单词之一站在某人和言语之间)。哪个正则表达式满足这个要求?我尝试了几种方法,但都没有按我的预期工作。有人可以帮我吗?

【问题讨论】:

标签: c++ regex


【解决方案1】:

我会避免使用regex,因为一旦你引入regexNow you have 2 problems

给定:

  1. 我们搜索范围的开头:const auto first = "Somebody"s
  2. 我们搜索范围的结尾:const auto second = "words"s
  3. 范围内不应存在的单词集合:const vector<string> words = { "in"s }
  4. 输入字符串:const auto input = "Somebody has typed in some words here."s

我们可以这样做:

const auto start = input.find(first) + size(first);
const auto finish = input.find(second, start);

if (start != string::npos && finish != string::npos) {
    istringstream range(input.substr(start, finish - start));

    if (none_of(istream_iterator<string>(range), istream_iterator<string>(), [&](const auto& i) { return find(cbegin(words), cend(words), i) != cend(words); })) {
        cout << "match\n";
    } else {
        cout << "not a match\n";
    }
} else {
    cout << "not a match\n";
}

Live Example


如果您已与regex 结婚,则有一种方法可以使用regex 做到这一点。例如,如果words 包含:“in”、“lorem”和“ipsum”,您会想要类似:

\bSomebody\b(?:(\bin\b|\blorem\b|\bipsum\b).*|.)*?\bwords\b

然后我们只需要测试我们的匹配是否包含任何内容:

const regex re("\\b" + first + accumulate(next(cbegin(words)), cend(words), "\\b(?:(\\b" + words.front(), [](const auto& lhs, const auto& rhs) { return lhs + "\\b|\\b" + rhs; }) + "\\b).*|.)*?\\b" + second + "\\b");
smatch sm;

if (regex_search(input, sm, re) && sm[1].length() == 0U) {
    cout << "match\n";
} else {
    cout << "not a match\n";
}

Live Example

【讨论】:

  • 这看起来不错,虽然对于我这个新手来说有点难以理解。是否有这整件事或其中一部分的名称,以便我可以对此进行更多研究以便更好地理解它?
  • 你问算法有没有名字?不,但是我使用的所有内容都来自标准,因此您可以在 en.cppreference.com 上查找内容,如果您想修改内容,现场示例非常有用。我可以回答一个具体的问题吗?
  • 我先查找对我来说新的东西,然后我会回到这里看看我是否理解了所有内容,如果没有,我会在这里提出问题..谢谢!
  • 我已经查看了第二个解决方案,但我仍然专注于第一个解决方案。我大致了解那里发生了什么,但我不明白为什么第二个 if 的情况看起来确实如此。我认为这对我来说是最困难的部分。
  • 最后,有了新的 IDE,一切都可以正常工作了。直到今天我才开始使用 Visual Studio 并且已经喜欢上了它。所以这个缺陷似乎确实存在于 MinGW(或 Dev C++ IDE?我不确定)中。至于赚钱的部分:靠编程赚钱不是我的目标(训练了两个月怎么可能,哈哈),但是因为你已经明确提到了,这让我很好奇:到底是做什么的你的意思是最低要求?再次感谢您的广泛帮助!
【解决方案2】:

试试这个正则表达式:(somebody)(?!.*(?:typed|nice)).*(words)。它匹配第一个单词,后跟任意数量的空格和第二个单词。如果后面跟着任意数量的字符和特定单词,匹配将在某人之后停止。第 1 组匹配某人,第 2 组匹配单词。

【讨论】:

  • 这不合适,因为(也许我的问题不够准确)这是我正在搜索的两个单词之间的任何位置是否存在特定单词。假设我总是想匹配单词某人和单词,除非在它们之间的某个地方有键入的单词或单词 nice(typed 和 nice 只是随机示例)。所以表达式应该匹配句子“Somebody has write down some words”,而不是句子“Somebody has write down nice words”或句子“Somebody has typed in words”。这就是我要找的。​​span>
猜你喜欢
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
相关资源
最近更新 更多