我需要一个正则表达式来匹配包含字符串OKAY然后是一个可能的连字符,然后是零个或一个单词字符的表达式。在此之后,任何非单词字符被接受,然后是任何东西。对于匹配的表达式,如果后面没有单词字符,则OKAY将更改为OK,例如:如果后面的字母为A,则为OA。如果连字符存在,则将其删除。
OKAY => OK
OKAY- => OK
OKAYA => OA
OKAY-A => OA
OKAYAB => OKAYAB (no-match)
OKAY-AB => OKAY-AB (no-match)
例子之后可能会出现例如:.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)
我实现这个的问题是,因为连字符和单词字符都是可选的,所以我得到的“懒惰”匹配也匹配非通缉案例。 为了教育,我会很高兴有和没有预见的例子(如果可能的话)。
答案 0 :(得分: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)
表示“只有当我们位于字符串末尾或下一个字符是空格时才匹配”,也可以写为{{1} }} 这里真正棘手的部分是像(?=\s|\z)
这样的正则表达式看起来会起作用,但它不适用于像^OKAY-?(\w)?(\W.*)?$
这样的情况,因为最后OKAY-AB
和-?
将不匹配,然后(\w)?
将匹配字符串的其余部分。
我们需要做的是解决这个问题,因此(\W.*)?
不会回溯。如果.NET支持possessive quantifiers,那么这很简单,那么我们可以将其更改为-?
。
不幸的是,它们不受支持,因此我们需要使用atomic grouping。 -?+
可选地匹配(?>-?)
,但会在退出组后立即忘记所有回溯信息。请注意,原子组不会捕获,因此-
是捕获组1。
答案 1 :(得分:1)
要做到这一点,不要超前,你可以使用
^(OKAY)(((-\w?|\w)(\W.*)?)|[^-\w].*)?$
这匹配单词“OKAY”,然后是一个可选组,其中包含 一个-
,一个可选的单词字符,然后是一个可选的非单词字符,后跟任何组, 或不是-
的字符或后跟任何内容的字符。 ^
和$
分别匹配字符串的开头和结尾,因此它只会匹配可接受的字符串。
Lookaheads几乎没有什么区别。唯一的变化是在“OKAY”组之后对所有内容进行预测((?=...)
)。
要在.net中使用它,唯一需要的更改是转义字符串中的所有\
。
答案 2 :(得分:1)
不知道.NET正则表达式,但这是preg-style匹配的开始:
OKAY-?(\w?)([^\w-]\w+)?\s*$
如果$ 1为空,则输出为OK $ 2
否则,输出为O $ 1 $ 2.