正则表达式:在单个捕获组中返回不同的匹配顺序

时间:2019-05-17 17:37:45

标签: java python regex keycloak

我正在尝试从智能卡中提取用户身份,我需要匹配以下模式:CN=LAST.FIRST.MIDDLE.0000000000

并返回以下结果:FIRST.LAST

如果我用自己的代码执行此操作通常很容易:

# python example
string = 'CN=LAST.FIRST.MIDDLE.000000000'
pattern = 'CN=(\w+)\.(\w+)\.'
match = regex.search(pattern, string)

parsedResult = match.groups()[1] + '.' + match.groups()[0]

不幸的是,我正在使用Keycloaks X.509 certmap web form匹配模式。 我仅限于使用一个正则表达式,并且该正则表达式只能包含一个捕获组。这是HTML表单,因此这里没有使用任何实际代码,只有一个正则表达式。

似乎我需要拥有子捕获组,然后首先返回第二个匹配的组,然后再返回第一个匹配的组,所有这些都在主捕获组中。这样的事情有可能完成吗?

此外,我认为我们仅限于Java支持的任何功能,因为这是应用程序运行的基础。

2 个答案:

答案 0 :(得分:3)

我认为只有一个捕获小组不可能做到这一点。如果我正确阅读了keycloak的文档,则捕获组实际上是正则表达式的结果。因此,您可以按原始顺序匹配FIRST或LAST,或者两者都匹配,但不能重新排序。

答案 1 :(得分:0)

是的,有可能。此表达式可能会帮助您这样做:

CN=([A-Z]+)\.(([A-Z]+)+)\.([A-Z]+)\.([0-9]+)

Demo

enter image description here

RegEx

如果这不是您想要的表达式,则可以在regex101.com中修改/更改表达式。例如,如果需要,可以添加并减少表达式的边界,并大大简化表达式。例如,这也可以工作:

CN=(\w+)\.(\w+)(.*) 

RegEx电路

您还可以在jex.im中可视化您的表达式:

enter image description here

Python测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"CN=([A-Z]+)\.(([A-Z]+)+)\.([A-Z]+)\.([0-9]+)"

test_str = "CN=LAST.FIRST.MIDDLE.000000000"

subst = "\\2\\.\\1"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

JavaScript演示

const regex = /CN=([A-Z]+)\.(([A-Z]+)+)\.([A-Z]+)\.([0-9]+)/gm;
const str = `CN=LAST.FIRST.MIDDLE.000000000`;
const subst = `$2\.$1`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);