When I view-source a html page, I saw this in text/javascript tag:
playlist = [{
title: "",
thumnail: "//example.com/folder/c9cc7f89fe5c168551bca2111d479a3e_1515576875.jpg",
source: "https://examp.com/360/HX62.mp4?authen=exp=1517246689~acl=/82vL3DDTye4/*~hmac=977cefd9de63a29fde25c856e0fdfd2f",
sourceLevel: [
{
source: "https://examp.com/360/HX62.mp4?authen=exp=1517246689~acl=/82vL3DDTye4/*~hmac=977cefd9de63a29fde25c856e0fdfd2f",
label: '360p'
},
{
source: "https://examp.com/480/HX62.mp4?authen=exp=1517246689~acl=/SuCa7NnGEhM/*~hmac=80bc89a07b1f4ed87d584a89c623e946",
label: '480p'
},
{
source: "https://examp.com/720/HX62.mp4?authen=exp=1517246689~acl=/SuCa7NnGEhM/*~hmac=80bc89a07b1f4ed87d584a89c623e946",
label: '720p'
},
],
}];
I want to get strings in source and label, then I've write this code:
$page = curl ('https://example.com/video-details.html')
preg_match ('#sourceLevel:[{source: "(.*?)",label: \'360p\'},{source: "(.*?)",label: \'480p\'},{source: "(.*?)",label: \'720\'}#', $page, $source);
$data360 = $source[1];
$data480 = $source[2];
$data720 = $source[3];
echo $data360. '<br/>' .$data480. '<br/>' .$data720. '<br/>';
I know it can be wrong in somewhere, because I'm new to PHP. I'm hoping there is someone help me to correct my code. Many thanks!
You need to:
escape braces and square brackets in your regular expression as they have special meanings in regexes,
escape the single quotes in the string literal for which you chose the single quote as delimiter (which you corrected after I wrote this).
provide for the white space that can appear between several characters (e.g. before and after {) in your page string.
I would also suggest to match the source/labels each as separate matches, so that when there are not exactly three, you will still have them all.
Here is the suggested code:
preg_match_all('~\{\s*source\s*:\s*"(.*?)"\s*,\s*label\s*:\s*\'(.*?)\'\s*\}~',
$page, $sources);
$sources = array_combine($sources[2], $sources[1]);
This will provide the $sources variable as an associative array, keyed by the labels:
[
"360p" => "https://examp.com/360/HX62.mp4?authen=exp=1517246689~acl=/82vL3DDTye4/*~hmac=977cefd9de63a29fde25c856e0fdfd2f",
"480p" => "https://examp.com/480/HX62.mp4?authen=exp=1517246689~acl=/SuCa7NnGEhM/*~hmac=80bc89a07b1f4ed87d584a89c623e946",
"720p" => "https://examp.com/720/HX62.mp4?authen=exp=1517246689~acl=/SuCa7NnGEhM/*~hmac=80bc89a07b1f4ed87d584a89c623e946"
]
Related
I'm trying to create a command parser for a Discord bot for when it receives a message, but I am having issues with dealing with nested quotes. I have made it so that it can parse a string with double quotes and flags, but it does not handle nested quotes.
Here are my requirements:
Handle double quotes.
Handle nested double quotes.
Handle flags (can be anywhere after !command).
A flag without a specified value defaults to a value of true/1.
For example, the following string:
!command that --can "handle double" quotes "and \"nested double\" quotes" --as --well=as --flags="with values"
...should result in the following arguments: command, that, handle double, quotes, and "nested double" quotes and the following flags: "can": true, "as": true, "well": "as", "flags": "with values".
Here is what I have so far:
// splits up the string into separate arguments and flags
const parts = content.slice(1).trim().match(/(--\w+=)?"[^"]*"|[^ "]+/g)
.map(arg => arg.replace(/^"(.*)"$/, '$1'));
// separates the arguments and flags
const [ args, flags ] = parts.reduce((parts, part) => {
// check if flag or argument
if (part.startsWith('--')) {
// check if has a specified value or not
if (part.includes('=')) {
// parses the specified value
part = part.split('=');
const value = part.slice(1)[0];
parts[1][part[0].slice(2)] = value.replace(/^"(.*)"$/, '$1');
} else {
parts[1][part.slice(2)] = true;
}
} else {
parts[0].push(part);
}
return parts;
}, [[], {}]);
This currently parses into the following arguments: command, that, handle double, quotes, and \, nested, double\, quotes and the following flags: "can": true, "as": true, "well": "as", "flags": "with values".
I modified the first RegEx to allow \" in the middle of quoted values. The following line:
const parts = content.slice(1).trim().match(/(--\w+=)?"[^"]*"|[^ "]+/g)
...changed to:
const parts = content.slice(1).trim().match(/(--\S+=)?"(\\"|[^"])*"|[^ "]+/g)
Modifications
The "[^"]*" section was changed to "(\\"|[^"])*" to allow \" to validate, preventing the quoted value from being terminated by quotes with backslashes before them.
I changed the \w in (--\w+=)? to a \S resulting in (--\S+=)? to allow more letters to validate.
I want to be able to split a string from a repeating pattern. For exemple:
id||eq||2,id||eq||1
will give me id||eq||2 and id||eq||1
this is easy because the separator is ,. But unfortunately I can have the separator inside the splitted part:
id||eq||2,2,id||eq||1
and I would like to get id||eq||2,2 and id||eq||1
I tried something like this: (\w+\|{2}\w+\|{2}[\w,]+,?)
But it always take the first part of the next group and not the second group
id||eq||1,2,id||eq||2,1
I'm out of ideas, if some of you can help me ?
EDIT
To be more precise, I want to get an array of objects (lets call it RequestFilter[]) from an url (and the param in the url is already an array).
An object RequestFilter looks like this:
fieldwhich is a string and can only contain alphanumeric chars
type which is an enum, can either contain only alphanumeric chars
filter which can be any char ( like ,)
which give me this in the url:
?filter[]=field||type||filter
today I already get RequestFilter from an url, but now I have to get an array of RequestFilter. I could use any separator, but because the attribute filter can be anything there will always be a risk of conflict with it while splitting.
some more examples of strings I can have and the expected RequestFilter[]:
name||cont||pier
[{field: 'name', type: 'cont', filter: 'pier'}]
name||cont||a,id||in||2,3
[{field: 'name', type: 'cont', filter: 'pier'},{field: 'id', type: 'in', filter: '2,3'}]
id||in||2,3,4,5,address||eq||Paris,France
[{field: 'id', type: 'in', filter: '2,3,4,5'},{field: 'address', type: 'eq', filter: 'Paris,France'}]
EDIT 2
I was pretty sure it was possible to handle it with Regex but if you think it's not possible just tell me and I will try to find another way to handle it.
A solution using Negative lookahead assertion:
const str = 'id||eq||2,id||eq||1';
const str2 = 'id||eq||2,2,id||eq||1';
console.log(
str.split(/(?!,\d),/)
)
console.log(
str2.split(/(?!,\d),/)
)
str = 'id||eq||2,2,id||eq||1'
splitted = str.split('id||eq||')
splitted.forEach(function(item, index, arr) {
arr[index]= 'id||eq||'+item;
})
splitted.shift()
console.log(splitted)
You can split it by ',id' and then do some manipulations like below
let str='id||eq||2,2,id||eq||1'
//split by ',id'
let arr=str.split(',id');
//join with fixed pattern
let result=arr.join('___id');
//split with fix pattern again
let final_arr=result.split('___');
console.log(final_arr);
I have a string:
for (;;); {
"__ar": 1,
"payload": null,
"jsmods": {
"require": [
["ServerRedirect", "redirectPageTo", [],
["https:\/\/bigzipfiles.facebook.com\/p\/dl\/download\/file.php?r=100028316830939&t=100028316830939&j=11&i=5823694&ext=12121516&hash=AaBVNURld6wrKBcU", true, false]
]
],
"define": [
["KSConfig", []
}
I try to regex this to be:
https://bigzipfiles.facebook.com/p/dl/download/file.php?r=100028316830939&t=100028316830939&j=11&i=5823694&ext=12121516&hash=AaBVNURld6wrKBcU
I've used
var results = $(document).find("pre").html();
var regex1 = new RegExp(/["\w\.\/\;\?\=\-\&\\\\"]/);
var resultsReplace = regex1.exec(results);
console.log(resultsReplace);
but it is not working.
Can anyone help me, please?
Assuming it is always URL and the delimiter is always " we can use a much simpler regex here, like:
str.match(/http[^"]+/)[0]
So we looking for a string starting with http with any following characters except " since the match string never can get one because this is a delimiter.
LMK if cases are wider (not an url, may not start with http, etc.) and I'll adjust regex.
I have various strings with numbers in brackets like "[4]Motherboard, [25]RAM" how can I convert such a string to a JSON array (keeping both ids and values) like this:
{"data":[
{"id":"4","item":"Motherboard"},
{"id":"25","item":"RAM"}
]};
I'm tried using split(",") to create the array but I really can't find out how to get the inner data in this case.
You could use a regular expression, which takes the number and the string, and assign it as property to an object.
var string = "[4]Motherboard, [25]RAM",
data = string.split(', ').map(function (a) {
var p = a.match(/^\[(\d+)\](.+)$/);
return { id: p[1], item: p[2] };
});
console.log(data);
Here one way to do it. The pattern \[(\d+?)\](.+) works like this:
(…) is a capture group. Just means whatever matches within the brackets will be a token in the result.
\d means a digit
\d+ means a digit, one or more times
\d+? means a digit, one or more times, but as few as possibile before the pattern matches something else.
.+ means any character, one or more times.
[ and ] have a special meaning in regular expression, so if you actually want to match the characters themselves, you need to escape them like so \[ and \].
The double backslashes \\ are just a JS oddity when defining a regex via a string as opposed to using a /literal/. Just two ways of saying the same thing.
There's plenty of resources to learn regex syntax, and http://regex101.com is a great place to play with patterns and experiment.
var input = "[4]Motherboard, [25]RAM";
var pattern = '\\[(\\d+?)\\](.+)';
var result = input.split(',').map(function (item) {
var matches = item.match(new RegExp(pattern));
return {id: matches[1], val: matches[2]};
});
console.log(result)
function toArray(string) {
return {
data: string.split(",").map(function(str) {
str = str.trim();
return {
id: str.substring(1, str.indexOf("]")),
item: str.substring(str.indexOf("]") + 1),
};
}),
};
}
I need to have an array as following but the single quote before (s) causes error. JavaScript does not accept them. Is there any way to bypass the error or replace the single quotes with other characters like space?
I tried to use replace function but not sure how to use it. I used ' but it did not work.
var locations = [
[
'Alex's loc', '37.9908372',
'23.7383394', '0'
],
[
'John James's loc', '37.9908372',
'23.7383394', '1'
],
[
'Norman's loc', '38.075352',
'23.807885', '3'
],
[
'Jack Moore's loc', '37.9908372',
'23.7383394', '2'
]
];
Code
var locations = [
<c:forEach var="location" items="${locationes}" varStatus="loop">[
'${location.value.name}', '${location.value.latitude}',
'${location.value.longitude}', '${loop.index}', </c:forEach> ];
you can wrap the single quote with double quote, like:
var locations = [
[
"Alex's loc", '37.9908372',
]
];
Using a backslash \ character before the invalid quote will also work. This is called an escape sequence
'Alex\'s loc' // this is represented as the string => Alex's loc
This is also how you get litteral new lines in strings
'\n' or "\n" for new line.