如何捕获除最后一个外的所有正则表达式组?

时间:2019-02-13 20:03:36

标签: regex

如何将camelCase文本转换为大写的下划线,但删除后缀?

如果我有一个文本“ AbcdEfghIjklAlphabet”,如何捕获它,以使结果为“ ABCD_EFGH_IJKL”,后缀字母消失了?

仅使用正则表达式就可以做到吗?

2 个答案:

答案 0 :(得分:0)

您将不得不“锚定”目标的后端。一种可能的选择是“单词边界”零宽度断言:\b

一旦您知道比赛结束的位置,就对结尾处的任何模式插入一个严格的要求,然后不要捕获。像这样:

pattern = r'(capture-stuff-at-the-front)But-no-stuff-at-the-end\b'

现在,您将捕获除最后一个单词以外的所有内容。您只需要决定什么是前期工作,以及各种情况如何。所以:

  1. 如果首字母是小写,例如:isCondition是否要与之匹配?

  2. 如果只有一个单词,例如:Heavy是匹配项吗?

  3. 是否允许使用数字,如果允许,Rs232Cable将数字放在前面还是后面?

  4. 等等。我确定有些东西我没想到...

所以尝试一下:

pattern = r'((?: uppercase-letter lowercase-letters*)+uppercase-letter lowercase-letters+\b'

可以匹配PRPolicyRequestPolicy并捕获除最后一个Policy之外的所有内容。

import re
test = 'isCondition Heavy Rs232Cable PRPolicy RequestPolicy'
pattern = r'((?:[A-Z][a-z]*)+)[A-Z][a-z]+\b'

for m in re.findall(pattern, test):
    print(m)

输出为:

PR
Request

答案 1 :(得分:0)

该解决方案很简单,如果您使用的语言具有强大的regex引擎(例如Python),则可以完全在regex中完成而无需循环。

模式:([A-Z][a-z]*(?![a-z]*$))

替换:\U\1_

说明:

  • [A-Z][a-z]*-匹配一个大写字母,后跟任意数量的小写字母。

  • (?![a-z]*$)-断言与上述模式匹配的字符后没有任何数量的小写字母,然后是字符串的结尾,以防止最后一组匹配。

  • (...)-整个模式都用括号括起来,以便捕获匹配以供以后使用。

  • (替换)\U-将后面的输出转换为大写。

  • (替换)\1-输出第一个捕获组的值。