• Advertisement
Sign in to follow this  

Java Pattern Matcher reads white space wrong

Recommended Posts

As my project is beginning to take shape, most of the problems I've encountered, I've been able to solve, but this latest one cunningly beats me, not because of any complexities but  because I don't know whats going on under the hood of the parser.

I am using a pattern matcher() Pattern.compile("\\d+");  - (in JAVA) - to extract and read floats,   but there were problems as white spaces are being interpreted as 0.0

808.00.0472.00.036.00.0202.00.018.00.024.00.0
782.00.096.00.036.00.0202.00.018.00.024.00.0
909.00.01028.00.036.00.0202.00.018.00.024.00.0
931.00.01149.00.036.00.0202.00.018.00.024.00.0

but should, correctly, be something like this

808.0  472.0  36.0  202.0  18.0  24.0
782.0  96.0  36.0  202.0  18.0  24.0
909.0  1028.0  36.0  202.0  18.0  24.0
931.0  1149.0  36.0  202.0  18.0  24.0

It was wrong because it was making white space to be 0.0

As said It was wrong because it was making white space to be 0.0

My quick fix was to use an if statement that exclude 0.0.  

Well I got away with it until the inevitable began to happen,- some of the real data started turning out to be 0.0, so my if statement was excluding the  real data from being read.  Any help on how to get this fixed?  I need white space to be read as white space not as 0.0 

public void readDataFromSelectedTextFile( File fPathplusName  ){
	
		List<Float> numbers = new LinkedList<Float>();
	   try {
				bufferedReader = new BufferedReader(new FileReader(fPathplusName));
				while ((stringObjectData = bufferedReader.readLine()) != null){
					Pattern p = Pattern.compile("\\d+");
					Matcher m = p.matcher(stringObjectData);
					while (m.find()) {
					  numbers.add(Float.parseFloat(m.group()));
					}
				}
				ListIterator<Float>  floatIterator = numbers.listIterator();			
				int i=0, t=7, n=0;
				float s, size=0;                         
				
			    while( floatIterator.hasNext() ){
			    	if( (s = floatIterator.next()) > 0 ){
			    		...
                                      ...  plenty of good coding here ...
                                       ...
			    	}
			    }
		  } 
	      catch (FileNotFoundException e) {		
	    	  e.printStackTrace();
	      } 
	      catch (IOException e) {
	    	  e.printStackTrace();
	      }/**/
	}

 

Edited by grumpyOldDude

Share this post


Link to post
Share on other sites
Advertisement

I don't think whitespace is your problem.

 

I think your problem is that \d "digit" doesn't match '.' characters (I use C# not Java, but regular expressions should be basically the same, shouldn't they?), so when you see x.y  your regular expression finds x, skips . and then returns a second match for y.

 

Try using "[0-9\\.]+" instead, or if you want to be more exact:  "[\\-\\+]?[0-9]*(\\.[0-9]+)?"  (but this does not include the 10E+5 syntax.  left as an exercise to the reader)

Edited by Nypyren

Share this post


Link to post
Share on other sites

Oh dear, I completely forgot ...  Many thanks Nypyren,  your answer triggered further inspiration on how it works.  And so I replaced   Pattern p = Pattern.compile("\\d+");  with    Pattern p = Pattern.compile("\\d+\\.\\d+");   and  the algorithm read my data correctly. Thanks

Edited by grumpyOldDude

Share this post


Link to post
Share on other sites
1 hour ago, grumpyOldDude said:

Oh dear, I completely forgot ...  Many thanks Nypyren,  your answer triggered further inspiration on how it works.  And so I replaced   Pattern p = Pattern.compile("\\d+");  with    Pattern p = Pattern.compile("\\d+\\.\\d+");   and  the algorithm read my data correctly. Thanks

This will probably break if you ever have negative values, or forget to put in the fractional part.  That may or may not be a problem, depending on what your data is here.

Nypren's more exact regex would get around that.

If I knew I had a file full of white-space delimited floats, I would probably not bother with trying to use a regex at all, and instead, what I would probably do would be something like (also a C# guy...):

var numbers = new List<float>();
var lines = File.ReadAllLines("whatever.txt");
float f;
foreach (var line in lines){
	var values = line.Split(new[]{' ', '\t', '\r', '\n'}, StringSplitOptions.RemoveEmptyEntries));
	foreach( var value in values ) {
		if (float.TryParse(value, out f)){
			numbers.Add(f);
		}
	}
}

The Jamie Zawinski quote gets thrown out probably more than it should, but...

Quote

"Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By MaFaBit Games
      Hey guys,
      I have publishd my new game on Android called ProjektZ. The game is a 2D plattformer with pixel art design.
      ProjektZ is about to find one key to unlock the level exit and go to the next one. 
      While you are doing that, you have some red enemys, which are trying to stop you.
      I'm really happy about the release and i hope someone can give me some feedback.
      I have some other games too, but i think this one is my best try.
       
      The link to ProjektZ: https://play.google.com/store/apps/details?id=com.mafabit.projektz
       
      And last but not least, some screenshots
       




    • By Mavericky
      Get the code HERE.
      This project is a nod to those 1990 pocket games that were all the rage in the day. The eTamagotchi features P2P networking showcasing how you can have a single application be both the client and the server at runtime. It features a random digimon (digital monster) that keeps track of all battles it has. The code is meant for demonstration and learning purposes only. The README lists each point that can be improved upon including gameplay mechanics.
       

    • By EddieK
      Hi, so I'm trying to pack 4 color values into a single 32-bit float but I'm having some issues. The resulting color values which I am getting are not correct. What could be wrong here?
      This is the part of code where I pack the 4 bytes into a single float in Java
      byte [] colorBytes = new byte[4]; colorBytes[0] = (byte)(color.x*256); colorBytes[1] = (byte)(color.y*256); colorBytes[2] = (byte)(color.z*256); colorBytes[3] = (byte)(color.w*256); vertexManager.appendVertexColorData(ByteBuffer.wrap(colorBytes).order(ByteOrder.LITTLE_ENDIAN).getFloat()); I also tried this:
      bitSh.x = 1.0f/(256.0f*256.0f*256.0f); bitSh.y = 1.0f/(256.0f*256.0f); bitSh.z = 1.0f/(256.0f); bitSh.w = 1.0f; color.x = object.vertexColorData[i*4+0]*r; color.y = object.vertexColorData[i*4+1]*g; color.z = object.vertexColorData[i*4+2]*b; color.w = object.vertexColorData[i*4+3]*a; vertexManager.appendVertexColorData(color.dot(bitSh)); But it didn't work either, though it gave me different results, both are incorrect.
      This is the vertex shader:
      uniform mat4 MVPMatrix; // model-view-projection matrix attribute vec4 position; attribute vec2 textureCoords; attribute float color; varying vec4 outColor; varying vec2 outTexCoords; const vec4 bitSh = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0); const vec4 bitMsk = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0); vec4 unpack_float(const float value) { vec4 res = fract(value * bitSh); res -= res.xxyz * bitMsk; return res; } void main() { outTexCoords = textureCoords; outColor = unpack_float(color); gl_Position = MVPMatrix * position; }  
      And this is the fragment shader:
      precision lowp float; uniform sampler2D texture; varying vec4 outColor; varying vec2 outTexCoords; varying vec3 outNormal; void main() { gl_FragColor = texture2D(texture, outTexCoords) * outColor; }  
      Thanks in advance.
    • By Jamal Williams
      Hello, my name is Jamal and I've been interested in programming video games for a long time. I've attempted to make games in the past however, they never really got far or at least close enough to them being released. This is mainly because I was biting off more than I could chew. I know that before I ask this question, many people are going to discourage me from making an MMO. Please save those comments because I know exactly how hard it is to make an MMO. Which is why I am starting off small and then working towards making my game greater.
       
      Anyhow, I plan on releasing a 2D Java game that is going to be hosted on my websites server. I wanted to make the game multiplayer(obviously) but I also wanted to make a system in which the player would log-in and then be able to access their characters in their account and play the story. I'm recently learning about sockets however, I was wondering if anyone had a method or even the slightest idea of how to save a player's information so that it could be loaded back into the game?
      I already have an idea where whenever the player logs in, you create a new initiate of a Player Object and then pass certain variables through. For example, the player logs in from one GameState and then goes into another GameState in which the Player() is called. When the Player() is called, it passes these values and these values tell the game where the player needs to be, etc.
      public class Player { String name; String race; int attack; int defense; public Player(String name, String race, int attack, int defense) { this.name = name; this.race = race; this.attack = attack; this.defense = defense; //etc } } I could always store these values into a SQL database so that way whenever the player logs in, I can just pull these values from there however, I was wondering if there was a better method for saving the player's data. Any thoughts?
    • By EddieK
      Hi, so I have this game which I'm working on and I have implemented A* pathfinding algorithm, but the problem is that the game framerate drops significantly if there are more than 50-100 enemies which need to find path to player.
      I did some code analyzing and noticed that the part which takes longest to process is part where it searches for node with the lowest F score. Is there anyway I could speed the process up?
      Here's the code I'm using:
      public ArrayList<Node> getPath(Node start, Node end){ closedSet.clear(); openSet.clear(); openSet.add(start); cameFrom.clear(); start.gScore = 0; start.fScore = heuristicCostEstimate(start, end); while(openSet.size() > 0){ Node currentNode = lowestFScoreNode(openSet);//openSet.findLowestFScoreNode(); if(currentNode.equals(end)){ return reconstructPath(cameFrom, currentNode); } openSet.remove(currentNode); closedSet.add(currentNode); Node [] neighbours = getNeighbours(currentNode); for(int i = 0; i < neighboursCount; i++){ if(closedSet.contains(neighbours[i])) continue; openSet.add(neighbours[i]); float tentativeGScore = currentNode.gScore + heuristicCostEstimate(start, neighbours[i]); if(tentativeGScore >= neighbours[i].gScore) continue; cameFrom.put(neighbours[i], currentNode); neighbours[i].gScore = tentativeGScore; neighbours[i].fScore = neighbours[i].gScore + heuristicCostEstimate(neighbours[i], end); } } return null; } The lowestFScore node function just returns result of Collections.min() 
      Thanks in advance.
  • Advertisement