【问题标题】:Matching of strings with special characters匹配特殊字符的字符串
【发布时间】:2019-01-31 23:03:34
【问题描述】:

我需要生成一个可以匹配另一个既包含特殊字符的字符串。我写了我认为是一个简单的方法,但到目前为止还没有一个成功的匹配。

我知道 c++ 中的特殊字符以“\”开头。例如,单引号应写为“\'”。

string json_string(const string& incoming_str)
{
    string str = "\\\"" + incoming_str + "\\\"";
    return str;
}

这是我必须比较的字符串:

bool comp = json_string("hello world") == "\"hello world\"";

我可以在 cout 流中看到,实际上我正在根据需要生成字符串,但比较仍然给出 false 值。

我错过了什么?任何帮助将不胜感激。

【问题讨论】:

  • 字符串"\"hello world\""不等于"\\\"hello world\\\""
  • "\\\"" + incoming_str + "\\\"" 变成\"incoming_str\",而"\"hello world\"" 只变成"hello world"。而不是string str = "\\\"" + incoming_str + "\\\""; 尝试string str = "\"" + incoming_str + "\"";

标签: c++ string


【解决方案1】:

一种方法是过滤一个字符串并比较这个过滤后的字符串。例如:

#include <iostream>
#include <algorithm>

using namespace std;

std::string filterBy(std::string unfiltered, std::string specialChars)
{
    std::string filtered;

    std::copy_if(unfiltered.begin(), unfiltered.end(),
              std::back_inserter(filtered), [&specialChars](char c){return specialChars.find(c) == -1;});

    return filtered;
}

int main() {
    std::string specialChars = "\"";
    std::string string1 = "test";
    std::string string2 = "\"test\"";

    std::cout << (string1 == filterBy(string2, specialChars) ? "match" : "no match");

    return 0;
}

输出为match。如果您向specialChars 添加任意数量的字符,此代码也可以使用。

如果两个字符串都包含特殊字符,您还可以通过filterBy 函数输入string1。然后,类似:

"\"hello \" world \"" == "\"hello world "

也会匹配。

如果比较对性能至关重要,您可能还会使用两个迭代器进行比较,得到 log(N+M) 的比较复杂度,其中 N 和 M 分别是两个字符串的大小。

【讨论】:

    【解决方案2】:
    bool comp = json_string("hello world") == "\"hello world\"";
    

    这肯定会产生错误。您正在通过json_string("hello world") 创建字符串\"hello world\",但将其与"hello world" 进行比较

    问题出在这里:

     string str = "\\\"" + incoming_str + "\\\"";
    

    在 str 的第一个字符串文字中,您假设被视为转义字符的第一个反斜杠实际上并未被视为转义字符,而只是字符串文字中的反斜杠。您在最后一个字符串文字中执行相同的操作。

    这样做

    string str = "\"" + incoming_str + "\"";
    

    【讨论】:

    • 我明白你的意思。我认为 OP 期望 jason_string 像字符串对象一样工作。已更正!
    【解决方案3】:

    在 C++ 中,字符串 文字 由引号分隔。

    那么问题来了:如何定义一个本身包含引号的字符串文字?在 Python 中(为了比较),这很容易(但这里不感兴趣的这种方法还有其他缺点):'a string with " (quote)'

    C++ 没有这种替代的字符串表示形式1,相反,您只能使用转义序列(Python 中也可以使用 - 只是为了完整性...): 在字符串中(或字符)文字(但没有其他地方!),序列\" 将被结果字符串中的单引号替换。

    所以"\"hello world\"" 定义为字符数组将是:

    { '"', 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '"', 0 };
    

    请注意,现在不需要转义字符...

    在您的 json_string 函数中,您可以附加额外的反斜杠:

    "\\\""
    { '\', '"', 0 }
    //^^^
    

    请注意,我写'\' 只是为了说明!你会如何定义单引号?再次逃离! '\'' - 但现在您也需要转义转义字符,因此此处实际上需要将单个反斜杠写为 '\\'(相比之下,您不必转义字符串文字中的单引号: "i am 'singly quoted'" – 就像您不必转义字符文字中的双引号一样)。

    由于 JSON 也对字符串使用双引号,因此您很可能希望更改您的函数:

    return "\"" + incoming_str + "\"";
    

    甚至更简单:

    return '"' + incoming_str + '"';
    

    现在

    json_string("hello world") == "\"hello world\""
    

    会产生真正的...

    1 旁注(从同时删除的答案中窃取):从C++11开始,也有raw string literals。使用这些,你也不必逃避。

    【讨论】:

      猜你喜欢
      • 2014-05-09
      • 2020-12-25
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-28
      • 1970-01-01
      相关资源
      最近更新 更多