funsutton Posted August 30, 2008 Share Posted August 30, 2008 I am having trouble with putting this together in my head. Instead of explaining outright, I'm just going to give it to you by example. $string = "Today the high is 72F and the low is 36F. Tomorrow will be in the 60s." I want to convert each number there to Celsius based on an indicator from the url. I need to extract each number, convert each number, and replace each number back in the string. I figure it's going to have extract into an array, and it will require regex to find the different numbers and account for the F and s when searching. I can handle the actual conversion to Celsius, however I am not sure how to extract and replace the numbers. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 Ahem. <?php $string = "Today the high is 72F and the low is 36F. Tomorrow will be in the 60s."; $string = preg_replace('/\b(\d+)(\w)?\b/e', "round(($1 - 32) / 1. . (($2 == 's') ? 's' : (($2 == 'F') ? 'C' : ''))", $string); echo $string; ?> I could probably clean up the PHP part a bit, but it works. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 30, 2008 Author Share Posted August 30, 2008 wow man....you make that look really easy. I would have never come up with that...at least like that. now to figure out what you did Thanks! Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 wow man....you make that look really easy. I would have never come up with that...at least like that. now to figure out what you did Thanks! Ha, no problem. If you want me to describe all the steps, I will. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 30, 2008 Author Share Posted August 30, 2008 If you would, that'd be awesome. In the actual string I am using, it's more complicated in that it has brackets [], single quotes '....in fact, here's an example of the actual string. mpdData['narr'].day['1']=new mpdNDObj(new Date('2008','7','30'),'1','A few isolated thunderstorms developing during the afternoon. High 86F. Winds light and variable. Chance of rain 30%.','Tomorrow'); mpdData['narr'].day['2']=new mpdNDObj(new Date('2008','7','30'),'1','Isolated thunderstorms in the evening. Fair skies overnight. Low 67F. Winds light and variable. Chance of rain 30%.','Tomorrow night'); mpdData['narr'].day['3']=new mpdNDObj(new Date('2008','7','31'),'2','Times of sun and clouds. Highs in the low 80s and lows in the mid 60s.','Sunday'); Not sure if this changes anything....but I have a feeling it will. So far I haven't gotten any output.... Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 You're right. Fixed and tested: <?php $string = "mpdData['narr'].day['1']=new mpdNDObj(new Date('2008','7','30'),'1','A few isolated thunderstorms developing during the afternoon. High 86F. Winds light and variable. Chance of rain 30%.','Tomorrow');"; $string = preg_replace('/\b(\d+)([a-z]){1}\b/ei', "round(($1 - 32) / 1. . (($2 == 's') ? 's' : (($2 == 'F') ? 'C' : ''))", $string); echo $string; ?> Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 30, 2008 Author Share Posted August 30, 2008 Wow, that works like a champ. Converts every singe one of them. Again, thanks. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 No problem. =P Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 30, 2008 Author Share Posted August 30, 2008 So do you mind explaining it if it's not too much trouble? Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 Woops, forgot about that. Here we go: Regex: /\b(\d+)([a-z]){1}\b/ei / - opening delimeter \b - non-word boundary. This is to make sure that the numbers aren't inside of a word. ( - start of capture $1 \d - any digit from 0-9 + - more than 1 (we don't want to capture 0 digits!) ) - end of capture $1 ( - start of capture $2 [a-z] - any character from lowercase a through lowercase z ) - end of capture $2 {1} - capture one of the preceding token (we only want one character. I could have left this out because it's automatically one, but whatever) \b - non-word boundary. We want to make sure there's no more characters or anything. / - ending delimeter ei - Turns on "eval" mode and case-insensitivity. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 30, 2008 Author Share Posted August 30, 2008 Hey man, that's awesome. Very clear now. Check your pm in a minute. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 Hey man, that's awesome. Very clear now. Check your pm in a minute. No problem, lol. Glad to help. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 30, 2008 Share Posted August 30, 2008 Oh yeah, please mark this topic as solved. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 30, 2008 Author Share Posted August 30, 2008 DarkWater, I was wondering, what happens if there is a negative F value denoted with a - sign? Quote Link to comment Share on other sites More sharing options...
nrg_alpha Posted August 31, 2008 Share Posted August 31, 2008 Darkwater, some of your explanations is not quite correct... Regex: /\b(\d+)([a-z]){1}\b/ei / - opening delimeter \b - non-word boundary. This is to make sure that the numbers aren't inside of a word. ( - start of capture $1 \d - any digit from 0-9 + - more than 1 (we don't want to capture 0 digits!) ) - end of capture $1 ( - start of capture $2 [a-z] - any character from lowercase a through lowercase z ) - end of capture $2 {1} - capture one of the preceding token (we only want one character. I could have left this out because it's automatically one, but whatever) \b - non-word boundary. We want to make sure there's no more characters or anything. / - ending delimeter ei - Turns on "eval" mode and case-insensitivity. \b - non-word boundary. This is to make sure that the numbers aren't inside of a word. (actually, this IS a word boundery.. a non word boundery is written as \B). + - more than 1 (we don't want to capture 0 digits!) (the plus means one or more.. not more than one.. a bit of a difference ). \b - non-word boundary. We want to make sure there's no more characters or anything. (again, this does mean word boundery) Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 31, 2008 Share Posted August 31, 2008 Yeah, I realized that I said "non-word boundary" after I could no longer edit the post. >_< I know the difference, don't worry. And with the + thing...I was just trying to explain it simply and wasn't really paying attention. Good catches though. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 31, 2008 Share Posted August 31, 2008 <?php $string = "mpdData['narr'].day['1']=new mpdNDObj(new Date('2008','7','30'),'1','A few isolated thunderstorms developing during the afternoon. High 86F. Winds light and variable. Chance of rain 30%.','Tomorrow');"; $string = preg_replace('/\b(-?[\d]+)([a-z]){1}\b/ei', "round(($1 - 32) / 1. . (($2 == 's') ? 's' : (($2 == 'F') ? 'C' : ''))", $string); echo $string; ?> Read your PM, try that. Should work. For anyone who wants to know, he asked about negative temps because it wasn't catching them. This fixed it. >_< Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 31, 2008 Author Share Posted August 31, 2008 That worked, tested it on a fake string. Thanks! Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 31, 2008 Share Posted August 31, 2008 No problem. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 31, 2008 Author Share Posted August 31, 2008 Well, I was trying to use your code to do something a little different. I decided to make the phrase "Tomorrow's high will be in the 36s" to "Tomorrow's high will be in the 30s" So, my query looked like this: $unit = "m"; $string = "mpdData['narr'].day['1']=new mpdNDObj(new Date('2008','7','30'),'1','A few isolated thunderstorms developing during the afternoon. High 86F. Winds light and variable. Chance of rain 30%.','Tomorrow hights will be in the 90s'');"; if ($unit == "m") { $string = preg_replace('/\b(-?\d+)([a-z]){1}\b/ei', "round(($1 - 32) / 1. . (($2 == 's') ? 's' : (($2 == 'F') ? 'C' : ''))", $string); $string = preg_replace('/\b(-?\d+)(s){1}\b/ei', "floor($1 * .1) * 10 . ($2 == 's') ? 's'", $string); echo $string; } else { echo $string; } But, it's failing. Basically I am trying to round down to the nearest 10, the ones that have an "s" beside them, so that it makes more sense. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 31, 2008 Author Share Posted August 31, 2008 Actually, I do think this works....but it's converting all of the numbers. I want it to only convert the one's with an s, not an F or C. $string = preg_replace('/\b(\d+)(s){1}\b/ei', "floor($1 * .1) * 10 . (($2 == 's') ? 's' : '')", $string); Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 31, 2008 Author Share Posted August 31, 2008 I might be wrong....it might actually be working, and my testing be wrong. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 31, 2008 Share Posted August 31, 2008 $string = preg_replace('/\b(\d+)s\b/ei', "floor($1 * .1) * 10 . 's'", $string); Tested and it works with the code you just gave me. It just so happens that 86F rounds to 30C exactly under normal circumstances, so I think that your one works too, but mine is a bit shorter. I tried with different numbers to make sure it only worked on ones with 's' there. Quote Link to comment Share on other sites More sharing options...
funsutton Posted August 31, 2008 Author Share Posted August 31, 2008 Yeah, it does work. I didn't realize that 86 was 30.....so, but cool. Then I actually accomplished something myself. Well, with the code you gave me. Quote Link to comment Share on other sites More sharing options...
DarkWater Posted August 31, 2008 Share Posted August 31, 2008 Yeah, yours would have worked. Good job. But uhh, I'd still use mine because I got rid of the ternary operator in the PHP part because it's not necessary if you KNOW it's going to be an S anyway. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.