C ++中正则表达式的问题

时间:2017-07-09 18:10:32

标签: c++ regex

我尝试在C#中使用以下正则表达式,该表达式已在C++中使用,但它在C++中无效。

std::regex r = std::regex("([^%]*(%[.[0-9]*]?[a-z])*)*", std::regex::extended);

它设法匹配几个字符串并正确地拒绝其他字符串,但是在字符串上被卡住(真的卡住了 - 没有错误)&%34%小于可用的pbn%f%d"它应该拒绝(因为有一个%不会立即在法律后缀之前)。

使用std::regex r = std::regex("(([^%]*)(%(\\.([0-9]*))?[a-z])*)*");表现出与我之前描述的完全相同的行为。 (我假设这两个正则表达式是等价的 - 只有一个是规范形式,如C#使用,第二个是ECMAScript,如c ++默认值)

我不确定问题是什么。 此外,我想将整个字符串与该模式匹配,以便仅在整个字符串作为整体匹配时才匹配。所以我想为此目的使用regex_match。我在C ++中使用以下代码:

if (std::regex_match(str, r))

此外,在C#中我使用以下代码执行该检查(整个字符串作为一个整体匹配):

        Regex^ r = gcnew Regex("([^%]*(%[.[0-9]*]?[a-z])*)*", RegexOptions::IgnoreCase);
        Match^ m = r->Match(str);
        if (m->Success && m->Groups[0]->Length== str->Length)

举一个我希望正则表达式匹配的例子是:

在状态%s%d)中获得了事件%s%d),转移到州%s%d)...

一些%.34x事件

正则表达式应该与以下内容不匹配:

一些%内容。

用语言解释正则表达式应该做什么 - 它应该接受唯一的字符串,其中所有出现的(如果有的话)%的字母前面都有一个字母或一个.46456x(也就是一些数字和一个字母)并拒绝所有其他人。

更新: 有效的正则表达式是^([^%]|%((\\.)?[0-9]+)?[a-zA-Z])*$。问题是,与C#正则表达式不同,这个版本非常慢,并且ALOTTT会降低应用程序的速度。所以我想也许最好也许使用std :: regex_search来查找是否有一个%的出现不会立即跟随后者或者.NUMBERS然后是一封信或者通过NUMBERS然后是一封信。将会欣赏有关正则表达式的帮助。

更新2:

我使用的是正则表达式^.*%(?!([.]?[0-9]+)?[a-zA-Z]).*$,我将它与std :: regex_search一起使用。它比之前的解决方案快得多,但仍然比C#版本慢得多(43秒,而C#则少于6秒)。有没有办法优化它甚至更远?

3 个答案:

答案 0 :(得分:2)

在这里,字符串中的所有%必须符合要求 如果是这样,匹配整个字符串,如果不匹配,则不匹配
字符串。

我建议您使用if ( regex_search( sTarget, sRx, sMatch, flags ) )执行此操作 但是 regex_match()会做同样的事情。

^(?:[^%]*%(?:\.[0-9]*)?[a-z])+[^%]*$

扩展

 ^                             # BOS
 (?:                           # Cluster begin
      [^%]*                         # Not % characters
      %                             # % found
      (?: \. [0-9]* )?              # optional .###
      [a-z]                         # single a-z required
 )+                            # Cluster end, 1 to many times
 [^%]*                         # Not % characters
 $                             # EOS

答案 1 :(得分:1)

一个简单的正则表达式,适用于VC ++,适合您的描述

 <TextView
    android:id="@+id/tv_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:letterSpacing="0.05"
    android:textColor="#000000"
    android:gravity="center"
    android:textSize="17sp"
    tools:text="New In"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:background="@drawable/my_selector"
    android:layout_gravity="center"
    />

Live demo

(如果 std::regex("^([^%]|%(\\.[0-9]+)?[a-zA-Z])*$", std::regex::extended) 之后的数字应该是可选的,则将[0-9]+更改为[0-9]*

答案 2 :(得分:1)

这类似于sln,但它更短,并且不需要%部分匹配:

^(?:[^%]*(?:%\.?[0-9]*[a-z])?)*$

首先 - ^(行首)和$(行尾)之间的所有内容都是可选的,因此接受空字符串。

在可选的非捕获组(?:...)中,匹配除%之外的任何数量的任何内容。然后,可选地,匹配%,可选地后跟.,然后匹配任意数量的数字,最后是一个字母。重复这个次数。

(我和其他人一样回答,并且正如问题中提供的正则表达式所暗示的那样,假设OP并不意味着&#34;紧接着是一个字母&#34;,而是后跟一个,右边?)

See it here at regex101