v1shnu
v1shnu

Reputation: 2231

Regex to get value between two colon excluding the colons

I have a string like this:

something:POST:/some/path

Now I want to take the POST alone from the string. I did this by using this regex

:([a-zA-Z]+):

But this gives me a value along with colons. ie I get this:

:POST:

but I need this

POST

My code to match the same and replace it is as follows:

String ss = "something:POST:/some/path/";
Pattern pattern = Pattern.compile(":([a-zA-Z]+):");
Matcher matcher = pattern.matcher(ss);

if (matcher.find()) {
    System.out.println(matcher.group());
    ss = ss.replaceFirst(":([a-zA-Z]+):", "*");
}
System.out.println(ss);

EDIT:

I've decided to use the lookahead/lookbehind regex since I did not want to use replace with colons such as :*:. This is my final solution.

String s = "something:POST:/some/path/";
String regex = "(?<=:)[a-zA-Z]+(?=:)";

Matcher matcher = Pattern.compile(regex).matcher(s);

if (matcher.find()) {
    s = s.replaceFirst(matcher.group(), "*");
    System.out.println("replaced: " + s);
} 
else {
    System.out.println("not replaced: " + s);
}

Upvotes: 2

Views: 3394

Answers (4)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

There are two approaches:

  • Keep your Java code, and use lookahead/lookbehind (?<=:)[a-zA-Z]+(?=:), or
  • Change your Java code to replace the result with ":*:"

Note: You may want to define a String constant for your regex, since you use it in different calls.

Upvotes: 2

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626691

UPDATE

Looking at your update, you just need ReplaceFirst only:

String result = s.replaceFirst(":[a-zA-Z]+:", ":*:");

See the Java demo

When you use (?<=:)[a-zA-Z]+(?=:), the regex engine checks each location inside the string for a * before it, and once found, tries to match 1+ ASCII letters and then assert that there is a : after them. With :[A-Za-z]+:, the checking only starts after a regex engine found : character. Then, after matching :POST:, the replacement pattern replaces the whole match. It is totlally OK to hardcode colons in the replacement pattern since they are hardcoded in the regex pattern.

Original answer

You just need to access Group 1:

if (matcher.find()) {
    System.out.println(matcher.group(1));
}

See Java demo

Your :([a-zA-Z]+): regex contains a capturing group (see (....) subpattern). These groups are numbered automatically: the first one has an index of 1, the second has the index of 2, etc.

To replace it, use Matcher#appendReplacement():

String s = "something:POST:/some/path/";
StringBuffer result = new StringBuffer();
Matcher m = Pattern.compile(":([a-zA-Z]+):").matcher(s);
while (m.find()) {
    m.appendReplacement(result, ":*:");
}
m.appendTail(result);
System.out.println(result.toString());

See another demo

Upvotes: 2

Michael Wiles
Michael Wiles

Reputation: 21186

This is your solution:

regex = (:)([a-zA-Z]+)(:)

And code is:

String ss = "something:POST:/some/path/";

ss = ss.replaceFirst("(:)([a-zA-Z]+)(:)", "$1*$3");

ss now contains:

something:*:/some/path/

Which I believe is what you are looking for...

Upvotes: 1

ameenhere
ameenhere

Reputation: 2343

As pointed out, the reqex captured group can be used to replace.

The following code did it:

  String ss = "something:POST:/some/path/";
    Pattern pattern = Pattern.compile(":([a-zA-Z]+):");
    Matcher matcher = pattern.matcher(ss);

    if (matcher.find()) {
        ss = ss.replaceFirst(matcher.group(1), "*");
    }
    System.out.println(ss);

Upvotes: 2

Related Questions