0

我需要一个正则表达式来匹配包含字符串 OKAY 的表达式,然后是一个可能的连字符,然后是零个或一个单词字符。在此之后,任何非单词字符都被接受,然后是任何东西。对于匹配的表达式,如果后面没有单词字符,则 OKAY 将更改为 OK,如果后面的字母是 A,则更改为 eg:OA。如果连字符存在,则将其删除。

OKAY         =>       OK
OKAY-        =>       OK
OKAYA        =>       OA
OKAY-A       =>       OA
OKAYAB       =>       OKAYAB          (no-match)
OKAY-AB      =>       OKAY-AB         (no-match)

示例后面可以跟 eg: .CD 而不改变结果

OKAY.CD         =>       OK.CD
OKAY-.CD        =>       OK.CD
OKAYA.CD        =>       OA.CD
OKAY-A.CD       =>       OA.CD
OKAYAB.CD       =>       OKAYAB.CD          (no-match)
OKAY-AB.CD      =>       OKAY-AB.CD         (no-match)

我实现这一点的问题是,由于连字符和单词字符都是可选的,我得到“惰性”匹配,它也匹配不需要的情况。为了教育起见,我会欣赏有和没有前瞻的例子(如果可能的话)。

4

3 回答 3

2

这是一个适合您的正则表达式:

\bOKAY(?>-?)(\w)?([^\w\s]\S*)?(?!\S)

由于尚不清楚您使用的是哪种语言,因此这里是您将如何进行替换的伪代码。

"O" + (match.group(1) if match.group(1) else "K") + match.group(2)

这是一个rubular:http ://www.rubular.com/r/SE8MBkUUUo


编辑:我在评论后对上述正则表达式进行了一些更改,但下面的描述并未反映这些更改。以下是原始正则表达式的更改:

  • 更改^\b不需要从行首开始
  • \W变成了[^\w\s],这可以防止OKAY OKAY成为一场比赛
  • 更改.*\S*,匹配将在空格处结束
  • 改为$,表示“仅当我们在字符串末尾或下一个字符是空格时才匹配” (?!\S)(?!\S)也可以写成(?=\s|\z)

这里真正棘手的部分是,像这样的正则表达式^OKAY-?(\w)?(\W.*)?$看起来会起作用,但它不适用于像这样的情况,OKAY-AB因为最终 the-?和 the(\w)?都不匹配,然后(\W.*)?将匹配字符串的其余部分。

我们需要做的是解决这个问题,使其-?不会回溯。如果 .NET 支持所有格量​​词,这将很简单,那么我们可以将其更改为-?+.

不幸的是,它们不受支持,因此我们需要使用原子分组(?>-?)可以选择匹配 a -,但一旦退出组就会忘记所有回溯信息。请注意,原子组不捕获,(\w)?捕获组 1 也是如此。

于 2012-05-23T18:40:00.450 回答
1

要在没有前瞻的情况下执行此操作,您可以使用

^(OKAY)(((-\w?|\w)(\W.*)?)|[^-\w].*)?$

这匹配单词“OKAY”,然后是一个可选组,该组包含一个可选-的单词字符,然后是一个可选的非单词字符,后跟任何组,或者不是一个字符,也不是-单词字符,后跟任何字符。^和分别匹配字符串的$开头和结尾,因此它只会完全匹配可接受的字符串。

前瞻几乎不会有所作为。(?=...)唯一的改变是在 "OKAY" 组之后的所有内容上放置一个前瞻 ( )。

要将其与.net 一起使用,唯一需要的更改是转义\字符串中的所有内容。

于 2012-05-23T18:18:35.973 回答
1

不知道 .NET 正则表达式,但这是从 preg 样式匹配开始:

OKAY-?(\w?)([^\w-]\w+)?\s*$

如果 $1 为空,则输出为 OK$2

否则,输出为 1 美元 2 美元。

于 2012-05-23T18:49:32.377 回答