Hey guys, so i've posted here before about regex, and i was told that some of you may be able to check my regexes for errors after i have created them. I have one that looks like it should work to me, but it absolutely will not.

public static String hitInput = "[CHAT WINDOW TEXT] [Sun Nov 29 11:34:13] Guardian of Water attacks Kyton's Rebuke [BH] : *hit* : (20 + 108 = 128 : Threat Roll: 3 + 108 = 111)";
    public static String hitRegex = "^.*\\]\\s+(.+)\\s+attacks\\s+(.+)\\s+:\\s\\*(?:[a-z][a-z]+)\\*\\s+:\\s.*\\+\\s(\\d+)\\s.+\\s+:\\s$";

public static Pattern hitPattern = Pattern.compile(hitRegex);
    public static Matcher hitMatcher = hitPattern.matcher(hitInput);

//the tester

public static void hitMatch() {
        boolean matchesHit = hitMatcher.matches();
        if (matchesHit == true) {
            String one = hitMatcher.group(1);
            String two = hitMatcher.group(2);
            String three = hitMatcher.group(3);
            String four = hitMatcher.group(4);
            System.out.println(one);
        }
        else System.out.println("DOESNT MATCH");
    }

anyone know why this doesnt match?

TJ

Recommended Answers

All 9 Replies

Which terms are you trying to match here? Post a sample text along with the output you are expecting.

Also, the trick to creating complex regular expressions is to build the regular expression incrementally rather than writing it in a single go only to find it doesn't work as expected.

the sample text is the variable hitInput. What I am looking to gather is The two names ("Guardian of Water" and "Kyton's Rebuke [BH]"), the *hit* (minus the *'s) and the first 108.

and when you say "build it incrementally" what do you mean?

TJ

the sample text is the variable hitInput. What I am looking to gather is The two names ("Guardian of Water" and "Kyton's Rebuke [BH]"), the *hit* (minus the *'s) and the first 108.

and when you say "build it incrementally" what do you mean?

TJ

He means start small and work your way up.

junkstring
longerjunkstring
itsgettingreallycomplicated
substring
importantsubstring
reallyreallycomplicatedstringwithanimportantsubstring

Match the smaller pieces, then build upon it and put it together until you feel confident that you can match your longer pattern.

ah okay. i *think* i can do that for my lines... will give it a go and post back when i have tried.

in the mean time, has anyone been able to figure out why my original regex is not matching?

TJ

Never start off with your regular expression with greedy quantifiers unless you know what you are doing. The .* at the start of your expression gobbles up your entire line. Then it realizes that there are other patterns/characters to be matched i.e. the \\]\\s+(.+) and so the regex engine starts backtracking which is expensive.

> has anyone been able to figure out why my original regex is not
> matching?

Your regex is exhausted just before the "Threat" word i.e. your entire regex matches till the character 'T' of 'Threat'. Your use of $ at the end kills off the entire match and hence the engine doesn't report a match.

Also, your use of non-capturing parentheses (?:) confuses me; why use them? I've removed the non-capturing parentheses and added the .* at the end to get something like:

public class ScrapRegexTests {

    public static void main(final String[] args) {
        String hitInput = "[CHAT WINDOW TEXT] [Sun Nov 29 11:34:13] Guardian of Water attacks Kyton's Rebuke [BH] : *hit* : (20 + 108 = 128 : Threat Roll: 3 + 108 = 111)";
        String hitRegex = "^.*\\]\\s+(.+)\\s+attacks\\s+(.+)\\s+:\\s\\*([a-z][a-z]+)\\*\\s+:\\s.*\\+\\s(\\d+)\\s.+\\s+:\\s(.*)";
        
        Pattern pat = Pattern.compile(hitRegex);
        Matcher matcher = pat.matcher(hitInput);
        if(matcher.matches()) {
            System.out.println("Regex matched  : #" + matcher.group(1) + "#");
            System.out.println("Regex matched  : #" + matcher.group(2) + "#");
            System.out.println("Regex matched  : #" + matcher.group(3) + "#");
            System.out.println("Regex matched  : #" + matcher.group(4) + "#");
            System.out.println("Unprocessed String  : #" + matcher.group(5) + "#");
        } else {
            System.out.println("No match found!");
        }
    }

}

Regex matched : #Guardian of Water#
Regex matched : #Kyton's Rebuke [BH]#
Regex matched : #hit#
Regex matched : #108#
Unprocessed String : #Threat Roll: 3 + 108 = 111)#

I'm sure you can carry on from here. I *think* there are better ways of writing the same thing but I'd defer my solution till you post your working solution.

HTH.

Once i get the output to look like this using a simple substring statement, would you recommend i test against Regex statements or test substrings against strings? i'm thinking regex, but i am looking for input.

[CHAT WINDOW TEXT] [Sun Nov 29 11:34:10]
Attack Of Opportunity : Soul Devourer attacks Kyton's Rebuke [BH] : *miss* : (13 + 113 = 126)

substring approach won't work given that the length of entire string along with the player names and the attack rating is not constant or known in advance. Go with the regex approach IMO.

[CHAT WINDOW TEXT] [Mon Feb 08 08:42:03] [Server] ===== Server 314 (1 player) =====
[60 (Sor29/RDD10/Pal1)] (TJ's Radiant Sorcerer)
[60 Sor29/RDD10/Pal1] TJ's Radiant Sorcerer
[60 Sor29/RDD10/Pal1] TJ's Radiant Sorcerer
[60 Sor29/RDD10/Pal1] TJ's Radiant Sorcerer
[60 Sor29/RDD10/Pal1] TJ's Radiant Sorcerer
[60 Sor29/RDD10/Pal1] TJ's Radiant Sorcerer
You are on server 314.
There are 35 current players on Higher Ground.

Given text as posted above, what is the easiest way to parse the pieces inside parens? I'm not sure how to code this in a regex, as the names will end up needing to be stored as variables, along with the classes. so i am not sure how i would go about calling the regex either.

> Given text as posted above, what is the easiest way to parse the pieces
> inside parens?

You can split the given string on spaces which would yield tokens like 60 , Sor29/RDD10/Pal1] , TJ's , Radiant Sorcerer . The way you would interpret these tokens depends on you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.