首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用java中的java.util.regex来匹配输入中的特定格式?

如何使用java中的java.util.regex来匹配输入中的特定格式?
EN

Stack Overflow用户
提问于 2014-03-21 08:42:22
回答 1查看 217关注 0票数 2

输入

输入可以以以下任何形式显示,并具有以下强制性内容TXT{**Any comma separated strings in any format**}

代码语言:javascript
复制
String loginURL = "http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS}";
String loginURL1 = "http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}&TXT{UE-IP,UE-Username,UE-Password}";
String loginURL2 = "http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}&username=abcd&location={LOCATION}&password={PASS}";
String loginURL3 = "http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}";
String loginURL4 = "http://ip:port/path?username=abcd&password={PASS}";

所需输出

1.对应于loginURL.的OutputURL

代码语言:javascript
复制
String outputURL = "http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}";
String outputURL1 = "http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}";
String outputURL2 = "http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}";
String outputURL3 = "http://ip:port/path?";
String outputURL4 = "http://ip:port/path?username=abcd&password={PASS}";

2.删除模式(如果有的话)

代码语言:javascript
复制
String deletedPatteren = TXT{UE-IP,UE-Username,UE-Password}

我的尝试

代码语言:javascript
复制
String loginURLPattern = TXT+"\\{([\\w-,]*)\\}&*";

System.out.println("1. ");
getListOfTemplates(loginURL, loginURLPattern);
System.out.println();

System.out.println("2. ");
getListOfTemplates(loginURL1, loginURLPattern);
System.out.println();

private static void getListOfTemplates(String inputSequence,String pattern){
    System.out.println("Input URL : " + inputSequence);
    Matcher templateMatcher =  Pattern.compile(pattern).matcher(inputSequence);
    if (templateMatcher.find() && templateMatcher.group(1).length() > 0) {
        System.out.println(templateMatcher.group(1));
        System.out.println("OutputURL : " + templateMatcher.replaceAll(""));
    }
}

输出

代码语言:javascript
复制
1. 
Input URL : http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS}
UE-IP,UE-Username,UE-Password}&password={PASS
OutputURL : http://ip:port/path?username=abcd&location={LOCATION}&

2. 
Input URL : http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}&TXT{UE-IP,UE-Username,UE-Password}
UE-IP,UE-Username,UE-Password
OutputURL : http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}&

上述模式的缺点

如果我添加任何字符串containing character like #,%,@ in between TXT{},那么我的代码就会中断。

如何使用java.util.regex库实现它,以便用户可以在TXT{Any Comma Separated Strings}之间输入任何逗号分隔的字符串。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-21 08:57:59

我建议使用Matcher.appendReplacement

代码语言:javascript
复制
public static void main(final String[] args) throws Exception {
    final String[] loginURLs = {
        "http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS}",
        "http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}&TXT{UE-IP,UE-Username,UE-Password}",
        "http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}&username=abcd&location={LOCATION}&password={PASS}",
        "http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}",
        "http://ip:port/path?username=abcd&password={PASS}"};
    final Pattern patt = Pattern.compile("(\\?)?&?(TXT\\{[^}]++})(&)?");
    for (final String loginURL : loginURLs) {
        System.out.printf("%1$-10s %2$s%n", "Processing", loginURL);
        final StringBuffer sb = new StringBuffer();
        final Matcher matcher = patt.matcher(loginURL);
        while (matcher.find()) {
            final String found = matcher.group(2);
            System.out.printf("%1$-10s %2$s%n", "Found", found);
            if (matcher.group(1) != null && matcher.group(3) != null) {
                matcher.appendReplacement(sb, "$1");                
            } else {
                matcher.appendReplacement(sb, "$3");
            }
        }
        matcher.appendTail(sb);
        System.out.printf("%1$-10s %2$s%n%n", "Processed", sb.toString());
    }
}

输出:

代码语言:javascript
复制
Processing http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS}
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}

Processing http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}&TXT{UE-IP,UE-Username,UE-Password}
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}

Processing http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}&username=abcd&location={LOCATION}&password={PASS}
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}

Processing http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path

Processing http://ip:port/path?username=abcd&password={PASS}
Processed  http://ip:port/path?username=abcd&password={PASS}

正如你正确指出的那样,有三种可能的情况:

  1. "?{TEXT}&“-> "?”
  2. “&{TEXT}和”-> "&“
  3. "?{TEXT}“-> "”

所以我们需要做的是在regex中测试这些情况。下面是模式:

代码语言:javascript
复制
(\\?)?&?(TXT\\{[^}]++})(&)?

解释:

  • (\\?)?可选地匹配和捕获?
  • &?可选地捕获&
  • (TXT\\{[^}]++})匹配并捕获TXT,然后是{,其次是一个或大多数not } (占有式),然后是} (不需要转义)。
  • (&)?可选地匹配和捕获&

我们有三个小组:

  1. 潜在的?
  2. 所需文本
  3. 潜在的&

现在,当我们找到匹配时,我们需要用case 1..3的适当捕获替换

代码语言:javascript
复制
if (matcher.group(1) != null && matcher.group(3) != null) {
    matcher.appendReplacement(sb, "$1");                
} else {
    matcher.appendReplacement(sb, "$3");
}

如果组13都存在

我们必须是以防万一1;我们必须用"?“代替。在1组,所以是$1

否则,我们将在23的情况下

在案例2中,我们需要用"&“替换,在3中用"”替换。

万一23持有"&“,万一3保持”,那么在这两种情况下,我们都可以用$3代替。

在这里,我只使用匹配组捕获TXT{...}部件。这意味着,尽管前面的?&已被替换,但它不在String found中。我,你只想要{}之间的位,然后移动括号。

注意,我重用了Pattern --如果性能有问题,您也可以使用Matcher。您应该始终重用Pattern,因为创建它(非常)非常昂贵。如果可以的话,可以将它存储在static final中--这是线程安全,matchers不是。通常的方法是将Pattern存储在static final中,然后在方法的上下文中重用Matcher

而且,Matcher.appendReplacement的使用比当前的方法要高效得多,因为它只需要处理一次输入。您的方法将字符串解析两次。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22553911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档