Does anyone have an website they would recommend to me for learning Regex?

I have tried using the Sun's tutorial on Regex as well as the Pattern and Matcher classes that use Regex but I am not quite understanding it.

I'd like to use it to return the String values in "groups" whether a match has been made or not (because I don't care about the matches... I just want the String returned in the current parenthesized groups!).

Also further knowledge of Regex would be nice, but returning the value within a group alone would be a godsend.

Thanks --

--Alex

Recommended Answers

All 9 Replies

Returning results whether they match or not defeats the entire purpose of regex. If you want to split input into groups, you obviously have an idea as to how you want that data broken out. Those decisions drive the design of those capturing group patterns. They can be very broad or very narrow, but matching some pattern within the input has to drive the process of extracting groups.

There are plenty of tutorial on using regex:
http://www.google.com/search?q=regex+java+tutorial&btnG=Search&hl=en&sa=2
but it still always comes down to some trial and error to tweak the pattern to your needs.

If you can post a specific example of your input and what you are trying to capture from it, perhaps we can give you some specific pointers on it.

I've posted a small regex testing form here: http://www.daniweb.com/forums/post392585-8.html that I use sometimes to test and tweak patterns. It's pretty limited in it's intent, but perhaps you may find it useful in playing with your patterns and capturing groups.

Here's an example of something I have been testing without good results--

import java.util.regex.*;
import java.util.*;
import java.io.*;
import java.io.Console;

public class Equation_Solver{
	private static String temp, bS = "\\";
	private static ArrayList<Character> myChars;

	public static void main(String[] args) throws Exception{


		/*
		Console console = System.console();
		if (console == null) {
			System.err.println("No console.");
			System.exit(1);
		}
		while (true) {
			Pattern pattern =
			Pattern.compile(console.readLine("%nEnter your regex: "));
			Matcher matcher =
			pattern.matcher(console.readLine("Enter input string to search: "));
			boolean found = false;
			while (matcher.find()) {
					console.format("I found the text \"%s\" starting at " +
				   "index %d and ending at index %d.%n",
				matcher.group(), matcher.start(), matcher.end());
			found = true;
			}
			if(!found){
				console.format("No match found.%n");
			}
		}*/


	//	Pattern p = Pattern.compile("((A(B(C))))");
	//	Matcher m = p.matcher("ABC");

	//	System.out.println(m.groupCount());
	//	System.out.println(m.group(4));
	//	System.out.println(m.matches());
	//	System.out.println(m.group());

	//	String temp = "A    B C".replace(" ", "");
	//	System.out.println(temp);


			//Perform Calculation in order of operations (PEMDAS)
			temp = "(5 + 7*3*(x^2-9))".replace(" ", "");//changes the equation into a compressed String
			myChars = new ArrayList<Character>(0);

			for(char element : temp.toCharArray())
				if(element != '(' && element != ')') //places the values without paranthesis in the arraylist
					myChars.add(new Character(element));

			char otherChars[] = new char[myChars.size()]; //creating an array to hold the Char objects as primitive types

			for(int i = 0; i < otherChars.length; i++)
				otherChars[i] = (char)myChars.get(i); //cast the char objects into char primitive types


			Pattern p = Pattern.compile(temp);//takes our temp value with paranthesis and stores it in a Pattern
			String temp2 = String.valueOf(otherChars);
			System.out.println(temp2);
			temp2 = temp2.replace(" ", "");
			temp2 = temp2.replace("+", "\\+"); //
			temp2 = temp2.replace("-", "\\-"); //
			temp2 = temp2.replace("*", "\\*"); //
			temp2 = temp2.replace("/", "\\/"); //
			temp2 = temp2.replace("^", "\\^"); //

			Matcher m = p.matcher("" + temp2 + "");//compares the value without the paranthesis to the pattern
			                                                  //- a match should be present
			System.out.println(m.matches());
			System.out.println(temp2);
			System.out.println(m.groupCount());

/*
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		System.out.print("Enter text for finding groups of text: ");
		String inputStr = in.readLine();
		String patternStr = "(a(b*))+(c*)";

		// Compile and use regular expression
		Pattern pattern = Pattern.compile(patternStr);
		Matcher matcher = pattern.matcher(inputStr);
		boolean matchFound = matcher.find();

		if(matchFound)
		{
			// Get all groups for this match
			for(int i=0; i<=matcher.groupCount(); i++)
			{
				String groupStr = matcher.group(i);
				System.out.println(groupStr);
			}
		}*/
	}//end main


	/**
	Simplifies the Equation into an easier-to-solve equation.
	The process of simplifying consists of performing possible operations
	(ones where the values are defined) and replacing the results of those
	operations with the previously "subbed" operation.
	i.e. (5 + 2) would be replaced with 7, or 3 + 2 * 1 would be replaced with 5
	due to the rules of order of operations. Furthermore (x+1)*(x-1) would be replaced with
	x^2 - 1.
	In addition, like terms are replaced for proper terms.
	i.e. x + 2x will be replaced with 3x, 10x^2 + 5x^2 would be replaced with 15x^2.
	The process of simplifying repeats no more than characters n of the equation squared.
	For example, if there are 26 characters in the equation listed, the simplification check will run
	26 * 26 times.
	*/
	String simplify(String equation, char... variables)
	{
		if(isSolvable(equation, variables))
		{
			//Perform Calculation in order of operations (PEMDAS)
			temp = equation.replace(" ", "");//changes the equation into a compressed String
			myChars = new ArrayList<Character>(0);

			for(char element : temp.toCharArray())
				if(element != '(' && element != ')') //places the values without paranthesis in the arraylist
					myChars.add(new Character(element));

			char otherChars[] = new char[myChars.size()]; //creating an array to hold the Char objects as primitive types

			for(int i = 0; i < otherChars.length; i++)
				otherChars[i] = (char)myChars.get(i); //cast the char objects into char primitive types


			Pattern p = Pattern.compile(temp);//takes our temp value with paranthesis and stores it in a Pattern
			Matcher m = p.matcher(String.valueOf(otherChars));//compares the value without the paranthesis to the pattern
			                                                  //- a match should be present
			//Combine like-terms



			//Simplify (not solve) the equations

			return "";
		}
		else return "Unsolvable Equation: " + equation;
	}

	/**
	Checks the String equation to see if it is solvable.
	Procedure consists of checking the Equation for the variables
	listed and checking the syntax of the Equation.
	If one variable isn't accounted for, then the method
	will return false. Furthermore if a matching pair of paranthesis isnt
	found then the method will also return false.
	*/
	static boolean isSolvable(String equation, char... variables)
	{
		int leftParanthesisCount = 0, rightParanthesisCount = 0, variablesContained = 0;

		for(int i = 0; i < equation.toCharArray().length; i++)
		{
			if(equation.toCharArray()[i] == '(')
				leftParanthesisCount++;
			else if(equation.toCharArray()[i] == ')')
				rightParanthesisCount++;
			else if((int)equation.toCharArray()[i] > 64 && (int)equation.toCharArray()[i] <= 90)
				variablesContained++;
			else if((int)equation.toCharArray()[i] >= 97 && (int)equation.toCharArray()[i] < (97+26))
				variablesContained++;

			for(int j = 0; j < variables.length; j++)
				if(equation.toCharArray()[i] == variables[j])
					variablesContained--;
		}

		if(variablesContained != 0)
			return false;

		if(leftParanthesisCount != rightParanthesisCount)
			return false;

		return true;
	}

}//end class

From the above code you can see that I'm trying to do a search for the entire expression (I even go through the effort of deleting white space then I check for all of the symbols in the equation).

I basically want to fragment the equation in groups, based on the parenthesis. I commented out a lot of the other things I've tried from other websites (regular-expression checks via user input, etc).

Even so I still seem to be doing something wrong. The expression returns false, even after doing a search equivalent to--

Matcher m = p.matcher("[" + temp2 + "]");

--where the regex would then be the entire equation (WITH the operators used as characters) inside the brackets, so there should be groups of values based on when the variables are found but it returns false and I have no idea why.

-Alex

Well, from what I read you might be out of luck with an unlimited nesting level. Unless you just have to use regex, a stack-based parsing is probably your best bet.

From my limited playing around with patterns for it,

(5 + 7*3*(x^2-9))

is do-able with a recursive application of the pattern "\\((.+)\\)" (the double backslashes only needed for the Java string - not the desired regex pattern) against the match group, but expressions like

(5 + (7*3)*(x^2-9))

break down when the second pass against the fist match group yields

7*3)*(x^2-9

Perhaps that could be dealt with by using a secondary pattern, but I didn't have time to play with it exhaustively.

I was thinking of resorting to a stack long before I considered Regex.

I thought that it would be best for me to try Regex first, since there will be times I will have to account for a situation like--

"5 - ( 1 + cos(x + 2))"

--where I would want to retain a value without removing its parenthesis which leads to more complicated "searching" issues within the String.

I now see why it is not a mystery for programs to be expensive when evaluating string-based equations.

You should be able to step through the string pushing the tokens onto the stack (with appropriate operand and operator validation) and when you encounter a closing paren, pop from the stack back to the last open paren, evaluate that result, and then push that result value onto the stack and proceed forward parsing.

You should be able to step through the string pushing the tokens onto the stack (with appropriate operand and operator validation) and when you encounter a closing paren, pop from the stack back to the last open paren, evaluate that result, and then push that result value onto the stack and proceed forward parsing.

That sounds ideal. Thanks a million.

the last post of this thread has the answer that will evaluate mathematical expressions i found it in a book

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.