I have a special strings to check with a PHP script. This is the format :
XX - XX:XX:XX - Somethings
such as :
each XX must be ?? or a pair of digit;
first XX can take every kind of digit;
second XX must be from 00 and 10;
third and fourth XX must be from 00 to 59;
somethings can be everything, it doesnt matter;
These are some example :
00 - ??:??:?? - Blablabla // OK
99 - ??:99:?? - Blablabla // NO (99 is too high)
99 - 12:50:40 - Blablabla // NO (12 is too high)
?? - AA:50:40 - Blablabla // NO (AA is not a pair of digit)
99 - 2:50:40 - Blablabla // NO (2 is not a pair of digit; I need 02)
99 -08:49:40 - Blablabla // NO (-08 need a space)
How can I do it? I think the best way is Regex, but I really don't know how to do it :) Any help is appreciated
You can do it like this
$subj = '00 - 04:38:27 - Hi';
preg_match('/^(\?\?|\d\d) - (\?\?|10|0\d):(\?\?|[0-5]\d):(\?\?|[0-5]\d) - (.*)/', $subj, $matches);
Then you can access the fields in matches:
$matches[1] = 00
$matches[2] = 04
$matches[3] = 38
$matches[4] = 27
$matches[5] = Hi
This seems to do the job (tested at http://www.spaweditor.com/scripts/regex/index.php)
/([0-9\?]{2} - (0[0-9]|10|\?\?):([0-5][0-9]|\?\?):([0-5][0-9]|\?\?) - .*)/
Related
I've got a complex directions URL and embed URL that I would like to get polylines for. Once I can get them into polylines or something similar I can convert to final format: GeoJSON.
Direction Link
-or-
Embed Link
I have looked at the API's and I can't find anything that accepts or would decode the PB (what is this? it's not a protocol buffer). So far this is as far as I've got:
//php
$pb_array = explode('!', $pb);
foreach($pb_array as $key => $value){
echo "$key - $value<br/>";
}
===
1 - 1m73
2 - 1m12
3 - 1m3
4 - 1d1472548.9575794793
5 - 2d-72.8191002664707
6 - 3d43.87505426780168
7 - 2m3
8 - 1f0
9 - 2f0
10 - 3f0
11 - 3m2
12 - 1i1024
13 - 2i768
14 - 4f13.1
15 - 4m58
16 - 3e0
17 - 4m5
18 - 1s0x0%3A0xa58b3d6041ba69f8
19 - 2sGuilford+Welcome+Center
20 - 3m2
21 - 1d42.8120069
22 - 2d-72.56614689999999
23 - 4m3
24 - 3m2
25 - 1d43.3893165
26 - 2d-72.40772249999999
27 - 4m5
28 - 1s0x4cb52e78df455c83%3A0xb6946ec850907db8
29 - 2s130+Lower+Michigan+Road%2C+Pittsfield%2C+VT+05762
30 - 3m2
31 - 1d43.76898
32 - 2d-72.815214
33 - 4m4
34 - 1s0x0%3A0xea2de48bba82cc86
35 - 3m2
36 - 1d44.042544
37 - 2d-72.6046997
38 - 4m5
39 - 1s0x0%3A0x6bb602ed58bf4413
40 - 2sJay+Peak+Resort
41 - 3m2
42 - 1d44.9379515
43 - 2d-72.5045433
44 - 4m5
45 - 1s0x4cb392aaa4333a07%3A0x160aef1559868340
46 - 2sDolly+Copp+Campground+Rd%2C+Gorham%2C+NH+03581
47 - 3m2
48 - 1d44.335842199999995
49 - 2d-71.21837339999999
50 - 4m5
51 - 1s0x4cb392684201a94d%3A0xfa4a6f490a05429d
52 - 2sMt+Washington+Auto+Road%2C+1+Mount+Washington+Auto+Road%2C+Gorham%2C+NH+03581
53 - 3m2
54 - 1d44.288384099999995
55 - 2d-71.22459599999999
56 - 4m5
57 - 1s0x4cb38e798f42c3d9%3A0xc3b88e4dac01db12
58 - 2sMt+Washington
59 - 3m2
60 - 1d44.270585399999995
61 - 2d-71.3032723
62 - 4m5
63 - 1s0x89e2a7fa444124d5%3A0xe3ed24b6f864eba0
64 - 2sWells%2C+ME
65 - 3m2
66 - 1d43.322232899999996
67 - 2d-70.5805209
68 - 4m5
69 - 1s0x89e2ba813e828c71%3A0x8cdf74380f6a933d
70 - 2sLibby's+Oceanside+Camp%2C+York+Street%2C+York%2C+ME
71 - 3m2
72 - 1d43.147162
73 - 2d-70.626173
74 - 5e1
75 - 3m2
76 - 1sen
77 - 2sus
78 - 4v1472497940601
The closest hints I could find are from this thread. I will keep looking but I'm stuck.
I'm trying to create an API based solution that has an input of one of these URL's and returns a GeoJSON.
would decode the PB (what is this? it's not a protocol buffer)
For the record, because this overflow question keeps popping up on google results: it is a protocol buffer. PB litteraly stands for protocol buffer.
It's just a different ASCII encoding (a compact URL encoding reminiscent of the binary encoding, not the usual JSON-like text encoding. When you squint at it it's not that much different than torrent's structure encoding), and Google doesn't provide us the .proto file.
For each field:
first character is the id (identifies the field according to the corresponding .proto file)
second character is the type of the field
m is for message
s is for string
i, j, u, v are for various type of ints
f, d are for floating points
e is for enum
the rest is the payload
So to unpack the fields you're seeing (even if we don't have the .proto file):
1m73 message of type 1, containing 73 elements (the whole message set)
1m12 submessage of type 1, contains 12 elements (probably information about the view box in the map box)
1m3 sub-sub-message type 1, contains 3 elements (probably map coordinates)
1d1472548.9575794793 first double field (probably zoom level)
2d-72.8191002664707 second double field (probably longitude)
3d43.87505426780168 third double field (probably latitude)
2m3 second sub-sub-sub message (no idea given that it's not filled. Maybe a starting point if you code a route instead of a single point ?)
1f0, 2f0, 3f0 the three members, currently just zero
3m2 third block (looks like a screen resolution)
1i1024, 2i768 : 1024x768 ? (and probably the omited field 3 would have been the color depth if present ??)
4f13.1 no idea, but it's a float
4m58 next message with 58 elements (to me it looks like a bunch of POI that we need to display in the box)
3e0 an enum, set to zero (this one would be completely impossible to interpret without a proto or without experimenting, as you need the list of enums)
4m5 five more elements probably a map poi
- 1s0x0%3A0xa58b3d6041ba69f8 string '0x0:0xa58b3d6041ba69f8', note the use of Url_encoded character. In turn it looks like a pair of hex numbers, maybe a GUID ?
- 2sGuilford+Welcome+Center string, the name with plus instead of blank (like most URLs)
- 3m2 two elements to come
- 1d42.8120069 and 2d-72.56614689999999 doubles probably map coordinates
4m3 again a message of type 4 in this level, so probably another poi
- 3m2, 1d43.3893165, 2d-72.40772249999999 but this one only specifies coordinates, and nothing else
4m5 another poi
- 1s0x4cb52e78df455c83%3A0xb6946ec850907db8 different pair of hex, GUID
...you got the idea...
5e1 another bunch of information probably general settings
3m2 this setting is a message (and looks like a locale)
1sen, 2sus locale is en_US
4v1472497940601 some other large number...
Note: the original proto that Google doesn't show us, is probably a single multi level structure. Thus, the sub-sub-message ID don't have always the same meaning: they aren't global ID, but ID within the parent message.
inside a sub message ID 1 (view box ?), the sub-sub message 3 seems to be resolution.
inside a sub message ID 4 (POIs ?), the sub-ID 3 isn't even a message but some enum
inside a sub message ID 5 (parameters), the sub-sub message 3 is a locale
Well, here's my sloppy but working solution. My needs required GeoJSON, but others can use the google maps service to get the desired output once you have the lat/lng array.
$embed = '<iframe src="https://www.google.com/maps/embed?pb=!1m73!1m12!1m3!1d1472548.9575794793!2d-72.8191002664707!3d43.87505426780168!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!4m58!3e0!4m5!1s0x0%3A0xa58b3d6041ba69f8!2sGuilford+Welcome+Center!3m2!1d42.8120069!2d-72.56614689999999!4m3!3m2!1d43.3893165!2d-72.40772249999999!4m5!1s0x4cb52e78df455c83%3A0xb6946ec850907db8!2s130+Lower+Michigan+Road%2C+Pittsfield%2C+VT+05762!3m2!1d43.76898!2d-72.815214!4m4!1s0x0%3A0xea2de48bba82cc86!3m2!1d44.042544!2d-72.6046997!4m5!1s0x0%3A0x6bb602ed58bf4413!2sJay+Peak+Resort!3m2!1d44.9379515!2d-72.5045433!4m5!1s0x4cb392aaa4333a07%3A0x160aef1559868340!2sDolly+Copp+Campground+Rd%2C+Gorham%2C+NH+03581!3m2!1d44.335842199999995!2d-71.21837339999999!4m5!1s0x4cb392684201a94d%3A0xfa4a6f490a05429d!2sMt+Washington+Auto+Road%2C+1+Mount+Washington+Auto+Road%2C+Gorham%2C+NH+03581!3m2!1d44.288384099999995!2d-71.22459599999999!4m5!1s0x4cb38e798f42c3d9%3A0xc3b88e4dac01db12!2sMt+Washington!3m2!1d44.270585399999995!2d-71.3032723!4m5!1s0x89e2a7fa444124d5%3A0xe3ed24b6f864eba0!2sWells%2C+ME!3m2!1d43.322232899999996!2d-70.5805209!4m5!1s0x89e2ba813e828c71%3A0x8cdf74380f6a933d!2sLibby's+Oceanside+Camp%2C+York+Street%2C+York%2C+ME!3m2!1d43.147162!2d-70.626173!5e1!3m2!1sen!2sus!4v1472497940601" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>';
$array = array();
preg_match( '/src="([^"]*)"/i', $embed, $array ) ;
list($pre, $pb) = split("pb=", $array[1]);
if($pb == "" || strpos($pb, "!") === false)
die(json_encode(array("success"=>false)));
//echo "PB Extracted:<br>";
//echo $pb;
///echo "<br><br>Decode:<br/>";
$pb_array = explode('!', $pb);
$coords = array();
$address;$addressHex;
$results = array();
foreach($pb_array as $key => $value){
//uncomment to debug output
//echo "$key - $value<br/>";
if($value == "3m2" || $value == "2m2"){
//3m2 seems to be the divider of these 'places'
if(count($coords) != 3) //don't add the center of map data (3 coordinates [height, lng, lat])
array_push($results, array("coords"=>$coords,"address"=>$address,"addressHex"=>$addressHex));
$coords = array(); //reset array
}else{
$type = substr($value, 1, 1);
$stype = substr($value, 0, 2);
$value = substr($value, 2);
//echo "$type - $value<br/>";
if($type == "d"){
//Found Lat,Lng
array_push($coords, $value);
}else if($stype == "2s"){
//Address
$address = $value;
}else if($stype == "1s"){
//Address Encoded in some way
$addressHex = $value;
}
}
}
//echo "<br><br>Google Result<br/>";
//echo json_encode($results);
//echo "<br><br>Mapbox API:<br/>";
$waypoints = array();
for($i=0;$i<count($results);$i++){
if(count($results[$i]["coords"])){
$lat = $results[$i]["coords"][0];
$lng = $results[$i]["coords"][1];
array_push($waypoints, "$lng%2C$lat");
}
}
$waypoints = implode("%3B", $waypoints); //convert to string
$mapbox_api_key = "pk.eyJ1I.....";
$url = "https://api.mapbox.com/directions/v5/mapbox/driving/$waypoints.json?steps=false&alternatives=false&overview=full&geometries=geojson&access_token=$mapbox_api_key";
//echo "<br><br>Mapbox Response:<br/>";
$response = file_get_contents($url);
$json = json_decode($response,true);
//echo "<br><br>Mapbox Geometry:<br/>";
$coordinates = $json["routes"][0]["geometry"]["coordinates"];
$geojson = (array("type"=>"FeatureCollection","features"=>array(array("type"=>"Feature","geometry"=>array("type"=>"LineString","coordinates"=>$coordinates),"properties"=>array()))));
echo json_encode(array("success"=>true, "geojson"=>$geojson));
I have a text file in following format.
Wed Aug 27 20:24:53.536 IST
address ref clock st when poll reach delay offset disp
*~172.16.18.163 .GPS. 1 657 1024 377 13.99 1.801 19.630
~127.127.1.1 .LOCL. 3 15 64 377 0.00 0.000 1.920
* sys_peer, # selected, + candidate, - outlayer, x falseticker, ~ configured
file has been generated dynamically I need to fetch value of 'st' (1) value next to '.GPS.' . text '.GPS.' is going to be same in every file.
Check my following code:
$f1_content = file_get_contents('filename.txt');
if(preg_match("/\b(.*)\s(.*)\s[0-9]\s\b/i", $f1_content, $match))
{
print_r($match); die();
}
not getting any match. Any idea how it can be done?
You can follow this:
#\.GPS\.\s+\K(\d+)#is
PHP:
preg_match("#\.GPS\.\s+\K(\d+)#is", $f1_content, $match)
If you may have more than of occurrences of that, you should use preg_match_all
Live demo
(?=.*?\.GPS\.).*?GPS\.\s*(\d+)
Try this.This works.
See demo.
http://regex101.com/r/pP3pN1/12
My testcase as follows:
echo crypt('string', '_....salt');//error
echo crypt('string', '_A...salt');//fast
echo crypt('string', '_AAAAsalt');//slow
Explanation as stated at http://www.php.net/manual/en/function.crypt.php:
CRYPT_EXT_DES - Extended DES-based hash. The "salt" is a 9-character
string consisting of an underscore followed by 4 bytes of iteration
count and 4 bytes of salt. These are encoded as printable characters,
6 bits per character, least significant character first. The values 0
to 63 are encoded as "./0-9A-Za-z". Using invalid characters in the
salt will cause crypt() to fail.
A dot is a printable character so why does it return an error? And which "order" applies on the used characters resulting "AAAA" more iterations than "A..."?
It says all in the quoted paragraph:
- least significant character first
- The values 0 to 63 are encoded as "./0-9A-Za-z"
So in your example "_....salt" would mean 0 rounds which obviously can't work.
and "_A...salt" is less than "_AAAAsalt" considering the least significant character comes first.
"_...Asalt" would also be more than "_A...salt"
This question is a bit old, however i found this when trying to wrap my head around how to create a hashing class for internal use here, and i came up with this little function which will base64 encode an integer with the appropriate characters/significance to be used as the 4 character 'iteration count'. Possible values are from 1 to 16,777,215
private function base64_int_encode($num){
$alphabet_raw = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$alphabet = str_split($alphabet_raw);
$arr = array();
$base = sizeof($alphabet);
while($num){
$rem = $num % $base;
$num = (int)($num / $base);
$arr[]=$alphabet[$rem];
}
$arr = array_reverse($arr);
$string = implode($arr);
return str_pad($string, 4, '.', STR_PAD_LEFT);
}
Hope it helps someone!
The code of Klathmon is nice but has some mistakes:
First - alphabet
It is:
./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
Should be:
./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
Second - order of characters/digits
It generates for example: ...z
But it should generate: z...
The improved code:
function base64_int_encode($num) {
$alphabet_raw='./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$alphabet=str_split($alphabet_raw);
$arr=array();
$base=sizeof($alphabet);
while($num) {
$rem=$num % $base;
$num=(int)($num / $base);
$arr[]=$alphabet[$rem];
}
$string=implode($arr);
return str_pad($string, 4, '.', STR_PAD_RIGHT);
}
A number system used in Extended DES:
.... - 0 (Extended DES error)
/... - 1
0... - 2
1... - 3
2... - 4
3... - 5
4... - 6
5... - 7
6... - 8
7... - 9
8... - 10
z... - 63
./.. - 64
//.. - 65
0/.. - 66
1/.. - 67
Y/.. - 100
61.. - 200
g2.. - 300
E4.. - 400
o5.. - 500
M7.. - 600
w8.. - 700
UA.. - 800
2C.. - 900
cD.. - 1000
zz.. - 4095
../. - 4096
/./. - 4097
0./. - 4098
1./. - 4099
xzzz - 16 777 213
yzzz - 16 777 214
zzzz - 16 777 215
And in connection with salt:
_/...salt - 1
_0...salt - 2
_1...salt - 3
_2...salt - 4
_3...salt - 5
_4...salt - 6
_5...salt - 7
_6...salt - 8
_7...salt - 9
_8...salt - 10
_z...salt - 63
_./..salt - 64
_//..salt - 65
_0/..salt - 66
_1/..salt - 67
_Y/..salt - 100
_61..salt - 200
_g2..salt - 300
_E4..salt - 400
_o5..salt - 500
_M7..salt - 600
_w8..salt - 700
_UA..salt - 800
_2C..salt - 900
_cD..salt - 1000
_zz..salt - 4095
_../.salt - 4096
_/./.salt - 4097
_0./.salt - 4098
_1./.salt - 4099
_xzzzsalt - 16 777 213
_yzzzsalt - 16 777 214
_zzzzsalt - 16 777 215
I need to verify if user have entered desired characters in the input field and if he didn't, I need to format input like this:
Start variable: +42 88 66 44 3, +42 (4) 87/654321; +42 3 123456
Desired variable: +428866443, +42487654321, +423123456
So basically I need to clear out all characters from variable that are not numbers and allow only signs like + , ; -.
Because I'm using an AJAX request, I would appreciate code for both PHP and Javascript.
For striping invalid chars from your string use regular expression in PHP and JAVASCRIPT.
PHP
$s = '+42 88 66 44 3, +42 (4) 87/654321; +42 3 123456';
$n = preg_replace('~[^\d\+,;-]~', '', $s);
print_r($n);
JAVASCRIPT
var s = '+42 88 66 44 3, +42 (4) 87/654321; +42 3 123456';
var n = s.replace(/[^\d\+,;-]/g, "");
console.log(n);
But better practice is that you show error, if user enters wrong format. You will need some validating to todo...
This may be a really silly question, but it just crossed my mind and I thought it would be interesting to know for sure....
So here is the scenario:
Users have 3 options for each day of the week: AM, PM, and OFF. These are mutually exclusive choices, so there is no option to work both an AM and PM on same day.
So if I wanted to store their AM shifts and PM shifts as separate bitmasks, and User1 chooses the following:
S M T W Th F Sa
A P X A X P A
I would have the following:
$shifts['User1']['AM'] = 73; // 1001001
$shifts['User1']['PM'] = 34; // 0100010
Now, if I just wanted to know which days User1 worked, I could obviously just do:
$shifts['User1']['All'] = $shifts['User1']['AM'] | $shifts['User1']['PM'];
Or even just:
$shifts['User1']['All'] = $shifts['User1']['AM'] + $shifts['User1']['PM'];
But what if I wanted the final result to distinguish AM from PM, something to the effect of:
$shifts['User1']['AM'] = A00A00A;
$shifts['User1']['PM'] = 0P000P0;
So that the A's and P's are both considered set, but that
A00A00A | 0P000P0 = AP0A0PA;
Is there a common way of doing this, or am I thinking about this totally wrong?
To represent three states in a binary fashion you need 2 bits. For instance, you could say that:
PM = 01
AM = 10
OFF = 00
So now you have this:
A00A00A translates to 10 00 00 10 00 00 10
0P000P0 translates to 00 01 00 00 00 01 00
Applying bitwise OR operation:
10 00 00 10 00 00 10
00 01 00 00 00 01 00
--------------------
10 01 00 10 00 01 10
A P 0 A 0 P A
You get AP0A0PA, your desired result.
To write a literal value in binary use: 0b1001001, or hex: 0x49, instead of decimal: 73.
The bitmap will only ever give you true or false, so there is no way to represent three values (AM, PM, X) by compressing two bitmaps into one.
I think you are thinking about this wrong (others may have a smarter solution that I can't think of though). An array of characters A, P, X might be as good for this. You can merge arrays (so it is not the same as a string).
Yes, it is possible. See the example below in Python:
>>> class WorkShift(str):
def __or__(self, val):
def shift_calc(x, y):
return x if x != '0' else y
return WorkShift(''.join(map(shift_calc, self, val)))
>>> WorkShift('A00A00A') | WorkShift('0P000P0')
'AP0A0PA'
Does it answer your question?
Ps. I used Python since you explicitly stated it can be any programming language. I overloaded | operator. Result of the operation is still WorkShift's instance, so you can use it for further processing. It also inherits from str, so you can use it as string as well.
EDIT:
Similar solution for PHP, but without operator overloading, based only on strings processing:
<?php
function shift_calc($x, $y) {
return $x != '0' ? $x : $y;
};
function shift_sum($am, $pm) {
return implode(array_map('shift_calc', str_split($am), str_split($pm)));
};
$result = shift_sum('A00A00A', '0P000P0');
where the $result is a string with the following value: "AP0A0PA" (see proof here: http://ideone.com/NbTEJ).
minitech's comment is correct. This is a ternary number system (because you have 3 choices for each value). So you could do this:
$shifts['User1']['AM'] = '1001001'; // A00A00A
$shifts['User1']['PM'] = '0200020'; // 0P000P0
$all = intval($shifts['User1']['AM'], 3) +
intval($shifts['User1']['PM'], 3);
echo base_convert($all, 10, 3);
You have two options here.
Interleave
The original bitmask is spread out, and the new bitmask is inserted in the new "holes".
APAPAPAPAPAPAP
Append
The new bitmask is appended to the old bitmask.
AAAAAAAPPPPPPP
The former is easier to inspect/compare, but the latter is more efficient with regards to speed.