I am creating a project for learning purpose:
FOR INFO : I have not used UIWebView
In my project I got HTML data(content) from server. This data contains all information about places(from google map). For getting specific data from HTML content I need to parse HTML. I parse HTML using Hpple. And I could successfully parse HTML to get specific data (Such as name,address…etc), but when I need to parse latitude and longitude from HTML content, I am confused about how to get latitude and longitude of places, because those are part of Javascript. I mean these latitude and longitude data are available in Javascript's functions.
Javascript content that I got from Server: (My limitation is that, I can only put piece of javascript code bacause this code is very very long)
function()
{
window.gHomeVPage=
{
title:'Hostel, Bhavnagar, Gujarat, India - Google Maps',url:'/?q\\x3dHostel,+Bhavnagar,+Gujarat,+India\\x26hq\\x3dHostel,\\x26hnear\\x3dBhavnagar,+Gujarat,+India\\x26t\\x3dm\\x26ie\\x3dUTF8',urlViewport:false,ei:'jp8tUb3uNK2ciAeQroGACw',
form:{
selected:'q',
q:{q:'Hostel, Bhavnagar, Gujarat, India',what:'Hostel,',near:'Bhavnagar, Gujarat, India'},d:{saddr:'',daddr:'',dfaddr:'Bhavnagar, Gujarat, India'},geocode:''},
query:{type:'l'},viewport:{center:{lat:21.757528,lng:72.15303},span:{lat:0.034314,lng:0.039956},zoom:14,mapType:'m',source:0},modules:['','strr','pphover','act_s','appiw','rst'],
overlays:{sxcar:false,
markers:
[{id:'A',cid:'7569356420090555589',latlng:{lat:21.747064,lng:72.169678},image:'http://maps.gstatic.com/intl/en_ALL/mapfiles/markers2/circleA.png',sprite:{width:20,height:34,top:0,image:'http://maps.gstatic.com/mapfiles/markers2/red_circle_markers_A_J2.png'},icon_id:'A',ext:{width:20,height:34,shadow:'http://maps.gstatic.com/intl/en_ALL/mapfiles/circle-shadow45.png',shadow_width:37,shadow_height:34,mask:false},drg:true,laddr:'Shree Sahajanand Girls Ptc Hostel, Ghogha Road, Bhavnagar, Gujarat 364001, India',geocode:'CfYWJFjKQj0mFXjVSwEdzjhNBCmN5-3pPlpfOTHF7NFVj8ELaQ',sxti:'Shree Sahajanand Girls Ptc Hostel',name:'Shree Sahajanand Girls Ptc Hostel',infoWindow:{title:'Shree Sahajanand Girls Ptc \\x3cb\\x3eHostel\\x3c/b\\x3e',addressLines:['Ghogha Road','Bhavnagar, Gujarat 364001, India'],phones:[{number:'0278 2562529'}],basics:'\\x3cdiv transclude\\x3d\\x22iw\\x22\\x3e\\x3c/div\\x3e',moreInfo:'more info',place_url:'http://maps.google.com/local_url?dq\\x3dHostel,+Bhavnagar,+Gujarat,+India\\x26q\\x3dhttps://plus.google.com/106028699675431268945/about%3Fhl%3Den\\x26s\\x3dANYYN7mCKtIBT1JPxwi6G2b9gVDdCuVyyA',zrvOk:true,loginUrl:'https://www.google.com/accounts/ServiceLogin?service\\x3dlocal\\x26hl\\x3den\\x26nui\\x3d1\\x26continue\\x3dhttp://maps.google.com/maps/place%3Fcid%3D7569356420090555589%26q%3DHostel,%2BBhavnagar,%2BGujarat,%2BIndia%26t%3Dm%26cd%3D1%26cad%3Dsrc:ppwrev%26ei%3Djp8tUb3uNK2ciAeQroGACw%26action%3Dopenratings',lbcurl:'http://www.google.com/local/add/choice?hl\\x3den\\x26gl\\x3dIN\\x26latlng\\x3d7569356420090555589\\x26q\\x3dHostel,\\x26near\\x3dBhavnagar,+Gujarat,+India',link_jsaction:''},ss:{edit:true,detailseditable:true,deleted:false,rapenabled:true,mmenabled:true},b_s:2,approx:true,elms:[4,1,6,2,12,1,9,1,5,2,11]
}
}
Here in above code I want to get value of lat: and lon: from latlng:{lat:21.747064,lng:72.169678}
For getting it from javascript, I googled and found that I need to use NSRegularExpression class for get specific matches(of Data) form content.
Then I tried with following code
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(?-imsx:latlng:)" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *arrayOfAllMatches = [regex matchesInString:locationStr options:0 range:NSMakeRange(0, [locationStr length])];
for (NSTextCheckingResult *match in arrayOfAllMatches)
{
NSString* substringForMatch = [locationStr substringWithRange:match.range];
NSLog(#"%#",substringForMatch);
}
I got output in console like this:
2013-02-28 11:35:25.051 MapExample[949:13d03] latlng:
2013-02-28 11:35:25.766 MapExample[949:13d03] latlng:
2013-02-28 11:35:26.208 MapExample[949:13d03] latlng:
2013-02-28 11:35:26.799 MapExample[949:13d03] latlng:
2013-02-28 11:35:27.303 MapExample[949:13d03] latlng:
2013-02-28 11:35:27.722 MapExample[949:13d03] latlng:
How can I get content of searched node from NSRegularExpression ?
If you really want to use a regular expression, this following pattern should work:
NSString *pattern = #"latlng:\\{lat:([0-9.]+),lng:([0-9.]+)\\}";
[0-9.]+ matches one or more characters which are a digit or ., and the parentheses around it make it a "capture group", so that the part of the string that matches this part of the pattern is available using rangeAtIndex:.
To verify this, I have added the exact input data from your question as a resource file "data.txt" to my test application, and loaded that data with
NSURL *url = [[NSBundle mainBundle] URLForResource:#"data.txt" withExtension:nil];
NSError *error;
NSString *locationStr = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
and then parsed the string with the regular expression
NSString *pattern = #"latlng:\\{lat:([0-9.]+),lng:([0-9.]+)\\}";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSArray *matches = [regex matchesInString:locationStr options:0 range:NSMakeRange(0, [locationStr length])];
for (NSTextCheckingResult *match in matches)
{
NSString *lat = [locationStr substringWithRange:[match rangeAtIndex:1]];
NSString *lng = [locationStr substringWithRange:[match rangeAtIndex:2]];
NSLog(#"latidude = %#, longitude = %#", lat, lng);
}
Output:
latidude = 21.747064, longitude = 72.169678
While not a direct answer to your question, there's actually an easier way to do this, using UIWebView:
+(NSString *)valueFromJSON:(NSString *)json andKey:(NSString *)key {
UIWebView webView = [[UIWebView alloc] init];
return [webView stringByEvaluatingJavaScriptFromString:[NSString withFormat:#"(function(){ var v = %#; return var.%#; }())", json, key]];
}
I'll apologize in advance for any syntax errors I've invariably made due to not being on my Mac and it being rather late. If you call this code repeatedly, it might be wise not to initialize a new WebView every time. This exploits the ability of WebKit's Javascript engine to do easy JSON parsing for you. Replace the return in the Javascript function to match your data structure.
I have a very big NSString, which holds around 1500 characters in it. In this string I need to extract a phone number, which may change frequently, as it is a dynamic data. The phone number will be in the format of 251-221-2000, how can I extract this?
Check out this previous question on regular expressions and NSString.
Search through NSString using Regular Expression
In your case an appropriate regular expression would be #"\\d{3}-\\d{3}-\\d{4}".
This sounds like a perfect candidate for a regular expression. You can use the NSRegularExpression class to achieve this. You can test your regular expression at http://www.regextester.com
NSString *yourString = #"Your 1500 characters string ";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"\d{3}-\d{3}-\d{4}"
options:NSRegularExpressionCaseInsensitive
error:&error];
[regex enumerateMatchesInString:yourString options:0 range:NSMakeRange(0, [yourString length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
// your code to handle matches here
}];
Let me know it is working or not.
I got this result
{lhs: "1 U.S. dollar", rhs: "44.5097254 Indian rupees", error: "", icc: true}
in NSString with ASIHTTPRequest method.
But I wanna read only 44.5097254 in one NSString. How to do so?
That's a JSON object, you need to parse it and then get the values you need.
Here's a nice tuto: http://ios-blog.co.uk/tutorials/parsing-json-on-ios-with-asihttprequest-and-sbjson/
You can get it with the following Methode
-(NSString*)getNumberFromString(NSString*)theString{
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"rhs: \"(([0-9]*[.]*[0-9]*)*)" options:NSRegularExpressionCaseInsensitive | NSRegularExpressionAnchorsMatchLines error:&error];
NSArray *matches = [regex matchesInString:theString options:0 range:NSMakeRange(0, [theString length])];
NSTextCheckingResult *match = [matches objectAtIndex:0];
return [theString substringWithRange:[match rangeAtIndex:1]]);
}
You can find more information about NSRegularExpressionin the Apple Documentation
If I had the following:
NSString *tweet = #"Shoutout to #somebody and #somebodyElse for your help on this one #shoutouts";
How would i go about finding the range of the twitter handles (eg #somebody)??
I want to make them bold in my Attributed String which is the next step.
Bonus points if you can help me find the # hash tags as well, but I assume its the same algorithm.
NSRegularExpression is your friend.
Use NSRegularExpression class,
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
Than trying using this online tool to build Regex,
http://www.gskinner.com/RegExr/
I tried this and it seems like you can build a good one,
SAMPLE CODE - NOT TESTED
NSString *yourString = #"Shoutout to #somebody and #somebodyElse for your help on this one #shoutouts";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"\#\S+|#\S+"
options:NSRegularExpressionCaseInsensitive
error:&error];
[regex enumerateMatchesInString:yourString options:0 range:NSMakeRange(0, [yourString length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
// your code to handle matches here
}];
About test in online tool!
Good luck!
example: word with number in string
NSString *str = [NSString stringWithFormat:#"this is an 101 example1 string"]
Since example1 has a number in the end and i want to remove it. I can break it into an array and filter it out using predicate, but that seems slow to me since I need to do like a million of these.
What would be a more efficient way?
Thanks!
Probably NSRegularExpression. I think ([^0-9 ]+)\d+|\d+([^0-9 ]+) should do it. Just replace it with $1.
Based on Chuck's response, here is the complete code in case someone might find it useful:
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"([^0-9 ]+)\\d+|\\d+([^0-9 ]+)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:str2
options:0
range:NSMakeRange(0, [str2 length])
withTemplate:#"$1"];