java regex - 应用程序名称替换

时间:2015-11-12 06:50:19

标签: java regex

我需要帮助才能从其工作名称中获取相关的app-name。

Job Name                                     | App Name
---------------------------------------------  ----------
JOB:Level1_OSP_DEF_1_1443534637_3mqku88i_1_0   OSP_DEF_1
JOB:Level0_GRSPOL_1423634637_20afoikl_1_1      GRSPOL
JOB:Level1_DSP_113_%I_3qqkv2vk_1_1             DSP_113
JOB:Level0_BPKMG_12_1238534637_2a4foik1_1_0    BPKMG_12

我尝试了一些正则表达式,但它并不能始终产生正确的结果。

JOB:*.*?_(.*?)_[*\d|%I]+_.*
JOB:*.*?_(.*?)_[t]*\d+?_.*

规则: -

1. The App name can have a max. of 9 characters including "_" in middle.
2. The App name is present after the 1st "_" and always ends with "_".
3. The Alphabets in App Name will always be in CAPS.

3 个答案:

答案 0 :(得分:2)

假设应用名称应该是符合3个已定义规则的最长子字符串(未说明的规则),并且作为名称它应限制为大写字母(规则#3),数字(未说明)规则)和下划线(规则#1):

private static String getAppName(String jobName) {
    Matcher m = Pattern.compile("^[^_]*_([A-Z0-9_]{1,9})_").matcher(jobName);
    if (m.find())
        return m.group(1);
    return null;
}

请注意,此正则表达式不会限制第一个_之前的文本,也不会限制终止应用名称的_之后的文本。这完全符合规则,没有任何此类限制。

测试

System.out.println(getAppName("JOB:Level1_OSP_DEF_1_1443534637_3mqku88i_1_0"));
System.out.println(getAppName("JOB:Level0_GRSPOL_1423634637_20afoikl_1_1"));
System.out.println(getAppName("JOB:Level1_DSP_113_%I_3qqkv2vk_1_1"));
System.out.println(getAppName("JOB:Level0_BPKMG_12_1238534637_2a4foik1_1_0"));

输出

OSP_DEF_1
GRSPOL
DSP_113
BPKMG_12

答案 1 :(得分:1)

这样的正则表达式适用于所有示例:

"JOB:Level\\d+_([A-Z0-9_]{1,9})_(\\d+|%I)_\\w+_\\d+_\\d+"

以下代码演示了它:

public class RegexTest {
    public static String extractJob(String input) {
        Pattern pattern = Pattern.compile("JOB:Level\\d+_([A-Z0-9_]{1,9})_(\\d+|%I)_\\w+_\\d+_\\d+");
        Matcher m = pattern.matcher(input);
        if (m.matches()) {
            return m.group(1);
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(extractJob("JOB:Level1_OSP_DEF_1_1443534637_3mqku88i_1_0"));
        System.out.println(extractJob("JOB:Level0_GRSPOL_1423634637_20afoikl_1_1"));
        System.out.println(extractJob("JOB:Level1_DSP_113_%I_3qqkv2vk_1_1"));
        System.out.println(extractJob("JOB:Level0_BPKMG_12_1238534637_2a4foik1_1_0"));
    }
}

答案 2 :(得分:0)

根据示例,我假设作业由六个字段连接,这六个字段由下划线分隔。找到应用程序名称的想法是删除第一个和后四个字段。如果更改了应用程序名称的规则(允许使用不同的字符或长度),这将使提取规则更简单,更健壮。

一个例子来解释。

JOB:Level1_OSP_DEF_1_1443534637_3mqku88i_1_0
    +----+ +-------+ +--------+ +------+ + +
       |       |          |         |    | |
       |       |          |         |    | +- field 6
       |       |          |         |    +--- field 5
       |       |          |         +-------- field 4
       |       |          +------------------ field 3
       |       +----------------------------- field 2
       +------------------------------------- field 1

代码重新开始,直到第一个_包含(JOB:Level1_在正则表达式中匹配[^_]*_)和尾部以_开头(之间的separtor)字段2和3)并包含另外三个_(字段4,5,6之间的分隔符)。 (_.*){4}在正则表达式中尾部是matchend。在正则表达式中,(.*)匹配字段1和字段4之间的匹配。

String[] jobs = { "JOB:Level1_OSP_DEF_1_1443534637_3mqku88i_1_0", 
    "JOB:Level0_GRSPOL_1423634637_20afoikl_1_1",
    "JOB:Level1_DSP_113_%I_3qqkv2vk_1_1",
    "JOB:Level0_BPKMG_12_1238534637_2a4foik1_1_0"};
for (String job : jobs) {
    System.out.printf("%-45s - %s%n", job, job.replaceAll("[^_]*_(.*)(_.*){4}", "$1"));
}

输出

JOB:Level1_OSP_DEF_1_1443534637_3mqku88i_1_0  - OSP_DEF_1
JOB:Level0_GRSPOL_1423634637_20afoikl_1_1     - GRSPOL
JOB:Level1_DSP_113_%I_3qqkv2vk_1_1            - DSP_113
JOB:Level0_BPKMG_12_1238534637_2a4foik1_1_0   - BPKMG_12