在 C++ 中匹配正则表达式的惯用方法
Posted
技术标签:
【中文标题】在 C++ 中匹配正则表达式的惯用方法【英文标题】:Idiomatic way to match a regular expression in C++ 【发布时间】:2013-11-15 10:21:45 【问题描述】:我想在 C++ 中比较两个字符串:
-
有一个函数
getName()
返回一个字符串。
现在我可以写 Out << getName();
这将打印字符串。
但是,如果字符串的值为arpit
或arpit*N*
,其中N 是整数,我想打印字符串only。如果它的值为arpita
、arpitx
,我不想打印它,其中 N 不是整数或空字符串。
我知道这很容易做到,但我想用最少的行数做到这一点。
到目前为止我所做的是:
char name1[] = getName();
char name2[] = "arpit";
for (int x = 0; x <= 4; x++)
if (name1[x] == name2[x]) continue;
else return ( Out << "not equal") ;
while(name1[x] ! = "\0")
if(isdigit(name1[x])
x++;
else return (Out << "not equal") ;
Out << getName();
更新 1
getName()
在遇到空格之前返回一个字符串,并且不会返回任何行或 2 个或更多单词。
【问题讨论】:
嗯。你试过什么?表现出一些努力,拜托。仅仅寻求这样的解决方案并不是 SO 的目的。std::string s = getName(); if (s.size() >= 5 && s.substring(0,5) == "arpit") Out << s;
boost::starts_with(getName(), "arpit")
呢?
使用“comaparison”解决问题标题过滤器的形式不佳。
@razlebe 他已经取消了更新 2。对于一个不断变化的问题,很难说什么。
【参考方案1】:
如果你有 C++11:
static std::regex const matcher( "arpit\\d*" );
if ( regex_match( name, matcher ) )
// matches...
如果您没有 C++11,boost::regex 几乎是相同的。
如果你没有C++11,而且你不能使用boost:
if ( name1.size() >= name2.size()
&& std::equal( name2.begin(), name2.end(), name1.begin() )
&& std::find_if( name1.begin() + name2.size(),
name1.end(),
[]( unsigned char ch ) return !isdigit( ch );
) == name1.end() )
// matches...
对于其余部分,您的代码有很多错误,不应该
编译。特别是,getName()
nothing
可以返回可用于初始化char []
;这
C++ 中字符串的类型是std::string
,而你的变量
应该是:
std::string name1( getName() );
std::string name2( "arpit" );
(除了你需要更好的名字。第二个可能是
例如reference
或header
。)
当然,调用isdigit
是未定义的行为
一个char
;您必须先转换为unsigned char
。
【讨论】:
【参考方案2】:auto s = getName();
if(s.size() >= 5 && s.substr(0,5) == "arpit")
Out << s;
【讨论】:
getName
是否返回对其他地方存在的东西的引用?他说它返回了一个字符串。除非它返回一个引用,否则将它分配给一个引用只是多余的废话(并且可能会稍微减慢程序的速度)。
这是对auto
的公然滥用,甚至可能导致程序不正确(例如getName()
返回char const*
。即使getName
返回std::string
,也没有必要混淆。
最后,当然,这不符合他的要求,因为它还会打印"arpita"
等。(更不用说比较第一个更有效的方法了5 个字符而不是创建一个子字符串。)【参考方案3】:
std::set<std::string> m_allowed_strings;
std::string validate_string(const string & s)
if(m_allowed_strings.find(s) != m_allowed_strings.end())
return s;
return "";
cout << validate_string(getName());
【讨论】:
看起来有点矫枉过正。我们需要拨打getName
两次吗?我们还没有被告知它实际上在做什么,例如,它可能会从名称文件中返回每一行。
我认为在这里使用set
是不可能的,而且这当然不合理。尽管他的示例在"arpit"
之后只有 1 个数字,但他的编码尝试表明可以有更多;这意味着有效字符串的集合是无限的。以上是关于在 C++ 中匹配正则表达式的惯用方法的主要内容,如果未能解决你的问题,请参考以下文章