I do not have any control over modifying the server endpoint to return a valid JSON.
Endpoint: http://newsrack.in/stories/servelots/iihs_feeds/16.json
sample response data:
`var _nr_metadata = {
site_base_url : "http://newsrack.in",
issue_name : "iihs_feeds",
category_name : "Chikungunya",
listing_url : "/stories/servelots/iihs_feeds/16"
}
var _nr_stories = [
{
title : "Delhi: Changing weather conditions cause 25 per cent rise in dengue cases",
url : "http://indiatoday.intoday.in/story/delhi-changing-weather-conditions-cause-rise-in-dengue-cases/1/1075570.html",
source : "India Today| Must Read",
date : "26.10.2017",
desc : "<a href=\'http://indiatoday.intoday.in/story/delhi-changing-weather-conditions-cause-rise-in-dengue-cases/1/1075570.html?utm_source=rss\'><img src=\'http://media2.intoday.in/indiatoday/images/stories/dengue305_102617022722.jpg\' align=\"left\" hspace=\"2\" height=\"180\" width=\"305\" alt=\"\" border=\"0\"/><\/a>Usually at this time of the year, the virus becomes inactive due to \ntemperature dip. But experts are witnessing the hostile nature of ades \nmosquitoes."
},
{
title : "Waste management bye-laws pending approval of LG: Delhi High Court told",
url : "http://indianexpress.com/article/delhi/waste-management-bye-laws-pending-approval-of-lg-delhi-high-court-told-4906249/",
source : "Delhi – The Indian Express",
date : "25.10.2017",
desc : "<img alt=\"\" border=\"0\" src=\"http://pixel.wp.com/b.gif?host=indianexpress.com&blog=53855017&post=4906249&subd=indianexpressonline&ref=&feed=1\" width=\"1\" height=\"1\" />"
},
{
title : "Alarm bells ringing:194 dengue cases in 2 weeks in district",
url : "http://www.tribuneindia.com/news/ludhiana/alarm-bells-ringing-194-dengue-cases-in-2-weeks-in-district/486718.html",
source : "The Tribune",
date : "25.10.2017",
desc : "Tribune News Service\nLudhiana, October 24\nThe number of dengue cases is rapidly increasing in the district as 194 confirmed cases have been recorded by the Health Department in the past two weeks.\nA total of 309 confirmed cases and 524 suspected cases of dengue have been reported in the district this year till Monday. According to the Health Department, cases are mostly being reported from the areas on Chandigarh Road in Ludhiana. These include 33-foot Road, GTB Nagar, Mundian Kalan, Guru Nanak Nagar, GK Estate, Jamalpur, Sectors 32 and 39. There are chances that the number of dengue cases could be higher than official reports, say residents.\nThe department had recorded 31 confirmed dengue cases till September 22 and 115 cases till October 10 in these places. Apart from these cases, as many as 10 confirmed cases of chikungunya, which is also spread by bite of infected aedes mosquitoes, have been reported here this year.\nHealth team finds mosquito larvae in 438 containers\nHealth Inspector Manpreet Singh ..."
},
{
title : "Alarm bells ringing:194 dengue cases in 2 weeks in district",
url : "http://www.tribuneindia.com/news/ludhiana/alarm-bells-ringing-194-dengue-cases-in-2-weeks-in-district/486718.html",
source : "The Tribune",
date : "25.10.2017",
desc : "Tribune News Service\nLudhiana, October 24\nThe number of dengue cases is rapidly increasing in the district as 194 confirmed cases have been recorded by the Health Department in the past two weeks.\nA total of 309 confirmed cases and 524 suspected cases of dengue have been reported in the district this year till Monday. According to the Health Department, cases are mostly being reported from the areas on Chandigarh Road in Ludhiana. These include 33-foot Road, GTB Nagar, Mundian Kalan, Guru Nanak Nagar, GK Estate, Jamalpur, Sectors 32 and 39. There are chances that the number of dengue cases could be higher than official reports, say residents.\nThe department had recorded 31 confirmed dengue cases till September 22 and 115 cases till October 10 in these places. Apart from these cases, as many as 10 confirmed cases of chikungunya, which is also spread by bite of infected aedes mosquitoes, have been reported here this year.\nHealth team finds mosquito larvae in 438 containers\nHealth Inspector Manpreet Singh ..."
},
{
title : "650 new cases of dengue, 48 of chikungunya",
url : "http://www.thehindu.com/news/cities/Delhi/650-new-cases-of-dengue-48-of-chikungunya/article19908528.ece",
source : "Hindu: Cities",
date : "24.10.2017",
desc : "More than 1,000 dengue cases reported so far this month"
},
'' // Last item -- needed because previous item ends with a comma
]`
as you can see the sample data is not valid JSON, i tried the below function, however ended up with unnecessary space in the keys, which is also a problem.
`
//Step 1
function extractjson(strarg){
var found = [], // an array to collect the strings that are found
rxp = /{([^}]+)}/g,
curMatch;
var parsed=[];
// step 2: regex to add quotes
var objKeysRegex = /({|,)(?:\s*)(?:')?([A-Za-z_$\.][A-Za-z0-9_ \-\.$]*)(?:')?(?:\s*):/g;
while( curMatch = rxp.exec( strarg ) ) {
found.push( curMatch[0].replace(objKeysRegex, "$1\"$2\":") );
}
//step 3- parse the found data
for(i=0;i<found.length;i++){
try {
json = JSON.parse(found[i]);
} catch (exception) {
json = null;
}
if (json) {
//the json is ok
parsed.push(JSON.parse(found[i]));
}else{
console.log("badjson");
//the json is not ok
}
}
console.log("input length =", found.length, "output length=", parsed.length);
return parsed;
}
}
`
Here's a fairly naive attempt at parsing...it makes some assumptions about the format of the data (for example it looks for the _nr_ prefix on variable names). I'd recommend splitting the string up into its various var declarations, and then cleaning up each section of data between them before evaluating using JSON.parse.
let parseJSON = (text) => {
let quoteKeysAndParse = (text) => {
//Quote keys in objects
let quoted = text.replace(/([\{\[,]\s*)(['"])?([a-zA-Z0-9_]+)(['"])?\s*:/g, '$1"$3": ');
//Remove the "last item" text
quoted = quoted.replace(/,\s+'' \/\/ Last item[^\]^}]+([\]\}])/g, '$1');
//Remove improperly escaping of apostrophes
quoted = quoted.replace(/([^\\])\\'/g, '$1\'');
//Parse the JSON
return JSON.parse(quoted);
}
//Find var declarations
let declarations = text.match(/var\s+_nr_[^\s]+\s+=\s+/ig), obj = {}, key = null, prevKey = null;
text = ['',text];
//For each variable...
for(let declaration of declarations){
key = declaration.match(/_nr_[^\s]+/)[0];
let currentText = text[1].split(declaration);
text = currentText;
if(prevKey){
//Parse the prior split section
obj[prevKey] = quoteKeysAndParse(text[0]);
}
prevKey = key;
}
//Make sure we process the last section
if(prevKey){
obj[prevKey] = quoteKeysAndParse(text[1]);
}
return obj;
}
fetch('https://cors-anywhere.herokuapp.com/newsrack.in/stories/servelots/iihs_feeds/16.json')
.then(response => response.text())
.then(parseJSON)
.then(data => {
for(let item of data._nr_stories){
let div = document.createElement('div');
div.innerHTML = `<h3>${item.date} - ${item.title} (${item.source})</h3><p>${item.desc}</p>`;
document.body.append(div)
}
});
Here's a working short solution
// ----------------------- DATA -----------------------
let code = `
var _nr_metadata = {
site_base_url : "http://newsrack.in",
issue_name : "iihs_feeds",
category_name : "Chikungunya",
listing_url : "/stories/servelots/iihs_feeds/16"
}
var _nr_stories = [
{
title : "Alarm bells ringing:194 dengue cases in 2 weeks in district",
url : "http://www.tribuneindia.com/news/ludhiana/alarm-bells-ringing-194-dengue-cases-in-2-weeks-in-district/486718.html",
source : "The Tribune",
date : "25.10.2017",
desc : "Tribune News Service\nLudhiana, October 24\nThe number of dengue cases is rapidly increasing in the district as 194 confirmed cases have been recorded by the Health Department in the past two weeks.\nA total of 309 confirmed cases and 524 suspected cases of dengue have been reported in the district this year till Monday. According to the Health Department, cases are mostly being reported from the areas on Chandigarh Road in Ludhiana. These include 33-foot Road, GTB Nagar, Mundian Kalan, Guru Nanak Nagar, GK Estate, Jamalpur, Sectors 32 and 39. There are chances that the number of dengue cases could be higher than official reports, say residents.\nThe department had recorded 31 confirmed dengue cases till September 22 and 115 cases till October 10 in these places. Apart from these cases, as many as 10 confirmed cases of chikungunya, which is also spread by bite of infected aedes mosquitoes, have been reported here this year.\nHealth team finds mosquito larvae in 438 containers\nHealth Inspector Manpreet Singh ..."
},
{
title : "650 new cases of dengue, 48 of chikungunya",
url : "http://www.thehindu.com/news/cities/Delhi/650-new-cases-of-dengue-48-of-chikungunya/article19908528.ece",
source : "Hindu: Cities",
date : "24.10.2017",
desc : "More than 1,000 dengue cases reported so far this month"
},
]
`
// --------------------- / DATA ------------------------
// --------------------- TREATMENT ------------------------
// Add '"' around the property names
code = code.replace(/\n +([a-z_]+) +:/g, '"$1" :').replace(/[\n\r]/g,'');
// To avoid unecessary ',' in "}, ]"
code = code.replace(/\},[ ]*\]/g,'}]');
// Split by var (keeping var name)
code = code.split(/ var(?=[a-z_ ]+= [\[\{])/);
// The result to feed
let result = {} ;
// Treat each var
code.forEach( d => {
d = d.trim();
if (!d) { return }
// Separate var name and var value
// Faster?
let index = d.indexOf('=');
let var_name = d.substr(0, index).trim();
let var_value = d.substr(index+1, d.length).trim();
// Parse the value
try
{
result[var_name] = JSON.parse(var_value);
}
catch(error)
{
console.error(error);
}
})
console.log(result);
Related
may I know is it possible the shipping fees is calculated by kilometer within a distance from my coordinate location?
For example, i already set a coordinate location that would be my physical store, and my shipping area only can deliver within 20 kilometer from my location.
How am i suppose to let customer can only choose the shipping area within 20 km from my location, and set a shipping fees on it?
Please help. Much appreciated and thank you all.
If you only need rough numbers and don't care if it's 20 or 23 km then you can use post codes.
If you want to you can "fine tune" each post code with street, and if needed with house number.
$UserPostCode = 12345;
$UserStreet = "3-street";
$Postcodes = [
"11111" => [
"A-street" => 12,
"B-street" => 10,
"C-street" => 15,
"Default" => 11
],
"12345" => [
"1-street" => 5,
"2-street" => 6,
"3-street" => 7,
"Default" => 5
]
];
if(isset($PostCodes[$UserPostCode])){
// post code is within your range
if(isset($PostCodes[$UserPostCode][$UserStreet])){
// you have a price set for this street
echo $PostCodes[$UserPostCode][$UserStreet]; //7
}else{
// This is a new street in the postcode unknown to you, give default price
echo $PostCodes[$UserPostCode]["Default"];
}
}else{
// customer lives out of range
echo "Sorry can't deliver to you";
}
As I wrote above you can fine tune the streets to house number 1-50 and 50 and higher if you like with the same logic as above.
I have a list of postcodes in the UK with a region id next to it. Now for delivering products it costs more depending on the region a user lives in.
For example, if a user lives in Birmingham and has a postcode that starts with B, he will get free delivery because that postcode region doesn't have any charge.
Likewise, if a user has a postcode starting with IM , they have to pay more delivery as that postcode region is more.
Sample postcode list:
Postcode | Region
AL | A
BA | A
BB | A
BD | A
B | B
BH | B
LN | D
LS | D
IV1 | E
IV23 | F
From the example above if a user wants to get a delivery and their postcode starts with BA then I want to apply the delivery charge rate of region A.
I'm actually a bit confused as to how I can programmatically do this. At first I thought I would simply do something similar to:
$postcodes = [
'AL'=>'A',
'BA'=>'A',
//And so on ....
];
//get the first 2 letters
$user_input = substr( $user_postcode, 0, 2 );
if(array_key_exists($user_input,$postcodes)){
//Get the region code
$region = $postcodes[$user_input];
// Charge the user with the delivery rate specific to that user, then carry on
}
But problem is that some similar postcodes can be in different regions, so for example, IV1 is region E and IV23 is region F like seen above.
That means I have to match a users post code on either, the 1 , 2 ,3 or 4 characters. That probably doesn't make sense. To elaborate more see below:
//From Birmingham and is in region B
$user1_input = 'B';
//From Bradford and is in region A
$user1_input = 'BD';
//From Inverness and is in region E
$user1_input = 'IV1';
So if the user input is from Birmingham and user input starts with B , how can i tell that apart from a postcode that also starts with B but then has other letters in it which makes it a different postcode.
I'm trying my best to explain, hopefully, this does make sense. If not please ask for more info.
Can anyone please help me with the logic to how I could achieve this? Either in Javascript or PHP , because i can convert the logic afterwards.
If you have what looks like a valid UK postcode, then remove the spaces and just search the array till you find a match:
$lookup = [
'' => 'X', // in case no match is found
'AL'=>'A',
'BA'=>'A',
//And so on ....
];
function get_delivery_for($postcode)
{
global $lookup;
for ($x=5; $x>0 && !$result; $x--) {
$result=$lookup[substr($postcode, 0, $x)];
}
return ($result);
}
Note that the code above is intended for illustration, I would recommend using something more elaborate to avoid it throwing warnings....
$result=isset($lookup[substr($postcode, 0, $x)])
? $lookup[substr($postcode, 0, $x)]
: false;
One option would be to order your postcode/region array by the descending length of the postcode key. This way, the longer (more specific) keys are checked first. Taking your list above, it would become something like this...
$postcodes = array(
"IV23" => "F",
"IV1" => "E",
"LS" => "D",
"LN" => "D",
"BH" => "B",
"BD" => "A",
"BB" => "A",
"BA" => "A",
"AL" => "A",
"B" => "B",
);
After you have that, it's as simple as looping through the array, checking for a match against the provided postcode (starting from the left), and stopping when you find a match.
foreach($postcodes as $code => $region)
{
if($code == substr($user_postcode, 0, strlen($code)))
{
$shippingRegion = $region;
break;
}
}
echo $shippingRegion;
I want to filter out the following information out of a long piece of text. Which I copy
and paste in a textfield and then want to process into a table as a result. with
Name
Address
Status
Example snippet:(Kind of randomized the names and addresses etc)
Thuisprikindeling voor: Vrijdag 15 Mei 2015 DE SMART BON 22 afspraken
Pagina 1/4
Persoonlijke mededeling:
Algemene mededeling:
Prikpostgegevens: REEK-Eeklo extern, (-)
Telefoonnummer Fax Mobiel 0499/9999999 Email dummy.dummy#gmail.com
DUMMY FOO V Stationstreet 2 8000 New York F N - Sober BSN: 1655
THUIS Analyses: Werknr: PIN: 000000002038905
Opdrachtgever: Laboratorium Arts:
Mededeling: Some comments // VERY DIFFICULT
FO DUMMY FOO V Butterstreet 6 8740 Melbourne F N - Sober BSN: 15898
THUIS Analyses: Werknr: AFD 3 PIN: 000000002035900
Opdrachtgever: Laboratorium Arts:
Mededeling: ZH BLA / BLA BLA - AFD 3 - SOCIAL BEER
JOHN FOOO V Waterstreet 1 9990 Rome F N - Sober BSN: 17878
THUIS / Analyses: Werknr: K111 PIN: 000000002037888
Opdrachtgever: Laboratorium Arts:
Mededeling: TRYOUT/FOO
FO SMOOTH M.FOO M Queen Elisabethstreet 19 9990 Paris F NN - Not Sober BSN: 14877
What I want to get out of it is this:
DUMMY FOO Stationstreet 2 8000 New York Sober
FO DUMMY FOO Butterstreet 6 8740 Melbourne Sober
JOHN FOOO Waterstreet 1 9990 Rome Sober
FO SMOOTH M.FOO Queen Elisabethstreet 19 9990 Paris Not sober
My strategy for the moment is using the following:
Filter all the lines with at least two words in capitals at the beginning of the line. AND a 4 digit postal code.
Then discard all the other lines as I only need the lines with the names and adresses
Then I strip out all the information needed for that line
Strip the name / address / status
I use the following code:
//Regular expressions
//Filter all lines which start with at least two UPPERCASE words following a space
pattern = /^(([A-Z'.* ]{2,} ){2,}[A-Z]{1,})(?=.*BSN)/;
postcode = /\d{4}/;
searchSober= /(N - Sober)+/;
searchNotSober= /(NN - Not sober)+/;
adres = inputText.split('\n');
for (var i = 0; i < adres.length; i++) {
// If in one line And a postcode and which starts with at least
// two UPPERCASE words following a space
temp = adres[i]
if ( pattern.test(temp) && postcode.test(temp)) {
//Remove BSN in order to be able to use digits to sort out the postal code
temp = temp.replace( /BSN.*/g, "");
// Example: DUMMY FOO V Stationstreet 2 8000 New York F N - Sober
//Selection of the name, always take first part of the array
// DUMMY FOO
var name = temp.match(/^([-A-Z'*.]{2,} ){1,}[-A-Z.]{2,}/)[0];
//remove the name from the string
temp = temp.replace(/^([-A-Z'*.]{2,} ){1,}[-A-Z.]{2,}/, "");
// V Stationstreet 2 8000 New York F N - Sober
//filter out gender
//Using jquery trim for whitespace trimming
// V
var gender = $.trim(temp.match(/^( [A-Z'*.]{1} )/)[0]);
//remove gender
temp = temp.replace(/^( [A-Z'*.]{1} )/, "");
// Stationstreet 2 8000 New York F N - Sober
//looking for status
var status = "unknown";
if ( searchNotsober.test(temp) ) {
status = "Not soberr";
}
else if ( searchSober.test(temp) ) {
status = "Sober";
}
else {
status = "unknown";
}
//Selection of the address /^.*[0-9]{4}.[\w-]{2,40}/
//Stationstreet 2 8000 New York
var address = $.trim(temp.match(/^.*[0-9]{4}.[\w-]{2,40}/gm));
//assemble into person object.
var person={name: name + "", address: address + "", gender: gender +"", status:status + "", location:[] , marker:[]};
result.push(person);
}
}
The problem I have now is that:
Sometimes the names are not written in CAPITALS
Sometimes the postal code is not added so my code just stops working.
Sometimes they put a * in front of the name
A broader question is what strategy can you take to tackle these type of messy input problems?
Should I make cases for every mistake I see in these snippets I get? I feel like
I don't really know exactly what I will get out of this piece of code every time I run
it with different input.
Here is a general way of handling it:
Find all lines that are most likely matches. Match on "Sober" or whatever makes it unlikely to miss a match, even if it gives you false positives.
Filter out false positives, this you have to update and tweak as you go. Make sure you only filter out what isn't relevant at all.
Strict filtering of input, what doesn't match gets logged/reported for manual handling, what does match now conforms to a known strict pattern
Normalize and extract data should now be much easier since you have limited possible input at this stage
Ideally, I'd like to skip the spaces on either side.
I've gotten as far as (: \S*), which obviously isn't really what I want.
getting the text between as groups would be great.
var str = "Retail Sales of Electricity : Colorado : Commercial : Annual";
str.match(/\b[^:]+\b/g);
You can try with:
var input = "Retail Sales of Electricity : Colorado : Commercial : Annual";
var output = input.split(':').map(function(s){ return s.trim(); });
How would i parse the json data below to out put as
Staring: Will Smith, Bridget Moynahan, Bruce GreenWood
{"query":{"\n| starring = [[Will Smith]]<br />[[Bridget Moynahan]]<br />[[Bruce Greenwood]]<br />[[James Cromwell]]<br />[[Chi McBride]]<br />[[Alan Tudyk]]}}
This was taken from here
{
"query": {
"normalized": [
{
"from": "I,_Robot_(film)",
"to": "I, Robot (film)"
}
],
"pages": {
"564947": {
"pageid": 564947,
"ns": 0,
"title": "I, Robot (film)",
"revisions": [
{
"contentformat": "text/x-wiki",
"contentmodel": "wikitext",
"*": "{{Other uses|I, Robot (disambiguation)}}\n{{Infobox film\n| name = I, Robot\n| image = Movie poster i robot.jpg\n| caption = Theatrical release poster\n| director = [[Alex Proyas]]\n| producer = [[Laurence Mark]]<br />[[John Davis (producer)|John Davis]]<br />Topher Dow<br />Wyck Godfrey\n| screenplay = [[Jeff Vintar]]<br />[[Akiva Goldsman]]\n| story = Jeff Vintar\n| based on = {{Based on|premise suggested by ''[[I, Robot]]''|[[Isaac Asimov]]}}\n| starring = [[Will Smith]]<br />[[Bridget Moynahan]]<br />[[Bruce Greenwood]]<br />[[James Cromwell]]<br />[[Chi McBride]]<br />[[Alan Tudyk]]\n| music = [[Marco Beltrami]]\n| cinematography = Simon Duggan\n| editing = Richard Learoyd<br />Armen Minasian<br />[[William Hoy]]\n| studio = [[Davis Entertainment]]<br />[[Laurence Mark Productions]]<br />[[Overbrook Entertainment|Overbrook Films]]<br/>[[Rainmaker Digital Effects]] (Provided)\n| distributor = [[20th Century Fox]]\n| released = {{Film date|2004|7|15|international|2004|7|16|United States}}\n| runtime = 115 minutes\n| country = United States\n| language = English\n| budget = $120 million\n| gross = $347,234,916\n}}\n'''''I, Robot''''' is a 2004 American [[dystopia]]n [[science fiction film|science fiction]] [[action film]] directed by [[Alex Proyas]]. The screenplay was written by [[Jeff Vintar]] and [[Akiva Goldsman]], and is inspired by (\"suggested by\", according to the end credits) [[Isaac Asimov]]'s short-story collection [[I, Robot|of the same name]]. [[Will Smith]] stars in the lead role of the film as Detective Del Spooner. The supporting cast includes [[Bridget Moynahan]], [[Bruce Greenwood]], [[James Cromwell]], [[Chi McBride]], [[Alan Tudyk]], and [[Shia LaBeouf]]. \n\n''I, Robot'' was released in [[North America]] on July 16, 2004, in [[Australia]] on July 22, 2004, in the [[United Kingdom]] on August 6, 2004 and in other countries between July 2004 to October 2004. Produced with a budget of [[United States dollar|USD]] $120 million, the film grossed $144 million domestically and $202 million in foreign markets for a worldwide total of $347 million. The movie received favorable reviews, with critics praising the writing, visual effects, and acting; but other critics were mixed with the focus on the plot. It was nominated for the 2004 [[Academy Award for Best Visual Effects]], but lost to ''[[Spider-Man 2]]''."
}
]
}
}
}
}
With the url being:
http://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=I,Robot(film)&rvsection=0
Your help would be greatly appreciated.
Thank You,
use:
var Jsonstring = {title: "Movie", actors: [ 'actor1','actor2']};
var movie = $.parseJSON(Jsonstring);
alert(movie.title); //will alert Movie
alert(movie.actors[0]) // will alert actor1
this function will convert your json string to javascript object.
http://api.jquery.com/jquery.parsejson/
You can parse it with RegExp:
var str = obj.query.pages[564947].revisions[0]['*'],
matches = str.match(/\|\s+(starring)\s+=\s+(.+)\n/),
result = matches[1] + ': ' + matches[2].replace(/<br\s+\/>/ig, ', ').replace(/[\[\]]/ig, '');
There will be starring: Will Smith, Bridget Moynahan, Bruce Greenwood, James Cromwell, Chi McBride, Alan Tudyk in the result variable.