0

I have a string line

String user_name = "id=123 user=aron name=aron app=application";

and I have a list that contains: {user,cuser,suser}

And i have to get the user part from string. So i have code like this

List<String> userName = Config.getConfig().getList(Configuration.ATT_CEF_USER_NAME);
String result = null;

for (String param: user_name .split("\\s", 0)){
for(String user: userName ){
    String userParam = user.concat("=.*");
    if (param.matches(userParam )) {
        result = param.split("=")[1];
    }
}   
}

But the problem is that if the String contains spaces in the user_name, It do not work. For ex:

String user_name = "id=123 user=aron nicols name=aron app=application";

Here user has a value aron nicols which contain spaces. How can I write a code that can get me exact user value i.e. aron nicols

8
  • put the values between delimiters? if you can't modify the text, then you have to split and take averything between two tokens as value Commented Apr 23, 2014 at 6:14
  • 2
    Well you've got a fundamental problem in your data format, by the looks of it. Are you absolutely stuck with that format, or can you fix it? Commented Apr 23, 2014 at 6:14
  • Although it is possible to write a parsing method for extracting keys and values from this string, the format is ... somewhat ... broken. You should really try to ease the format. Either don't allow spaces or put quotes around the text containing spaces (which still does not work well with the split method). Commented Apr 23, 2014 at 6:17
  • @JonSkeet No the data comes from an external application and I can not change it. I have to use it anyway. Commented Apr 23, 2014 at 6:18
  • 1
    @CODEFISH Splitting is only one way to handle it. Directly matching is cheaper (see my answer). Commented Apr 23, 2014 at 6:30

3 Answers 3

5

If you want to split only on spaces that are right before tokens which have = righ after it such as user=... then maybe add look ahead condition like

split("\\s(?=\\S*=)")

This regex will split on

  • \\s space
  • (?=\\S*=) which has zero or more * non-space \\S characters which ends with = after it. Also look-ahead (?=...) is zero-length match which means part matched by it will not be included in in result so split will not split on it.

Demo:

String user_name = "id=123 user=aron nicols name=aron app=application";
for (String s : user_name.split("\\s(?=\\S*=)"))
    System.out.println(s);

output:

id=123
user=aron nicols
name=aron
app=application

From your comment in other answer it seems that = which are escaped with \ shouldn't be treated as separator between key=value but as part of value. In that case you can just add negative-look-behind mechanism to see if before = is no \, so (?<!\\\\) right before will require = to not have \ before it.
BTW to create regex which will match \ we need to write it as \\ but in Java we also need to escape each of \ to create \ literal in String that is why we ended up with \\\\.

So you can use

split("\\s(?=\\S*(?<!\\\\)=)")

Demo:

String user_name = "user=Dist\\=Name1, xyz src=activedirectorydomain ip=10.1.77.24";
for (String s : user_name.split("\\s(?=\\S*(?<!\\\\)=)"))
    System.out.println(s);

output:

user=Dist\=Name1, xyz
src=activedirectorydomain
ip=10.1.77.24
Sign up to request clarification or add additional context in comments.

1 Comment

nice explanation. But i am curious about comment that I made on anubhva answer.
4

Do it like this:

First split input string using this regex:

" +(?=\\w+(?<!\\\\)=)"

This will give you 4 name=value tokens like this:

id=123
user=aron nicols
name=aron
app=application

Now you can just split on = to get your name and value parts.

Regex Demo

Regex Demo with escaped =

7 Comments

Thanks for the demo. I loved it. The data comes from HP archsight. So in that case if it conains = in username or value it will provide us a backslash for that. How to handle that. I am not so good in regex.
Can you tell me a sample line then I can sure look into it.
String s = "user=Dist\=Name1, xyz src=activedirectorydomain ip=10.1.77.24"; In this the user conatins a value which has = sign and which is escaped using backslash.
Thanks. Could you please explain this regex? It will be good for others too, who will look into this answer in future .
Well first may I know what's wrong with this answer as you didn't accept it even though my answer was posted first.
|
1

CODE FISH, this simple regex captures the user in Group 1: user=\\s*(.*?)\s+name=

It will capture "Aron", "Aron Nichols", "Aron Nichols The Benevolent", and so on. It relies on the knowledge that name= always follows user=

However, if you're not sure that the token following user is name, you can use this:

user=\s*(.*?)(?=$|\s+\w+=)

Here is how to use the second expression (for the first, just change the string in Pattern.compile:

String ResultString = null;
try {
    Pattern regex = Pattern.compile("user=\\s*(.*?)(?=$|\\s+\\w+=)", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    Matcher regexMatcher = regex.matcher(subjectString);
    if (regexMatcher.find()) {
        ResultString = regexMatcher.group(1);
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

3 Comments

hey nice answer but name will not always follow user. It is generated dunamically. and any field can be present after user.
I am writing this to eat my own words. Thanks zx81.
@CODEFISH You said "name will not always follow user." Hey no worries, I added a second method for that situation (also without splitting). :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.