How to remove currency abbreviations from right side of strings? - php

I have a sample array like this:
[
"BTCUSD",
"DASHBTC",
"DOGEUSD",
"LTCBTC",
"LTCUSD",
"SCBTC",
"STEEMBTC",
"WAVESBTC",
"SNGLSBTC",
"1STBTC",
"DASHUSD",
"BQXETH",
"PTOYETH",
"XAURETH",
"BTCUSDT"
]
How to get just one currency for every string? I can't use explode because there isn't a single/static delimiter. I can't use substr() or strpos() because the substrings vary.
So how to split it?
Update
This is my expected output
[
"BTC",
"DASH",
"DOGE",
"LTC",
"LTC",
"SC",
"STEEM",
"WAVES",
"SNGLS",
"1ST",
"DASH",
"BQX",
"PTOY",
"XAUR",
"BTC"
]

You need to have an array to your expected currencies and then filter against it.
Here is a quick and dirty solution: https://3v4l.org/6mMbN or with recursive function call: https://3v4l.org/mhjBD
<?php
$currencies = [
'USD',
'BTC',
'DASH',
'LTC',
'SC',
'STEEM',
'WAVES',
'SNGLS',
'1ST',
'BQX',
'ETH',
'PTOY',
'XAUR',
];
$input = [
"BTCUSD",
"DASHBTC",
"DOGEUSD",
"LTCBTC",
"LTCUSD",
"SCBTC",
"STEEMBTC",
"WAVESBTC",
"SNGLSBTC",
"1STBTC",
"DASHUSD",
"BQXETH",
"PTOYETH",
"XAURETH",
"BTCUSDT",
];
$output=[];
foreach($input as $doubleCurrency){
foreach($currencies as $currency){
$pattern = '/^'.$currency. '/';
preg_match($pattern, $doubleCurrency, $matches);
if(array_key_exists(0, $matches)){
$output[]=$matches[0];
}
}
}
var_dump($output);

You are always trimming the right side of the string, just use preg_replace() with an end of string anchor. No lookup array is necessary. It doesn't get much easier that this:
Code: (Demo)
$input=[
"BTCUSD",
"DASHBTC",
"DOGEUSD",
"LTCBTC",
"LTCUSD",
"SCBTC",
"STEEMBTC",
"WAVESBTC",
"SNGLSBTC",
"1STBTC",
"DASHUSD",
"BQXETH",
"PTOYETH",
"XAURETH",
"BTCUSDT"
];
var_export(preg_replace('/USDT$|USD$|ETH$|BTC$/','',$input));
Output:
array (
0 => 'BTC',
1 => 'DASH',
2 => 'DOGE',
3 => 'LTC',
4 => 'LTC',
5 => 'SC',
6 => 'STEEM',
7 => 'WAVES',
8 => 'SNGLS',
9 => '1ST',
10 => 'DASH',
11 => 'BQX',
12 => 'PTOY',
13 => 'XAUR',
14 => 'BTC',
)
(The pattern can be condensed if you don't mind the syntax. /USDT?$|ETH$|BTC$/ is a little faster.)

Here is an answer that is similar to Edwin's but is probably faster.
I use str_replace to create a space in-between the currencies then I loop the new array and remove anything after the first space.
Example:
'STEEMBTC' becomes STEEM BTC '.
Then substr it to: 'STEEM'.
Probably quicker code as it loops less and does not use regex.
$currencies = [
'USD',
'BTC',
'DASH',
'LTC',
'SC',
'STEEM',
'WAVES',
'SNGLS',
'1ST',
'BQX',
'ETH',
'PTOY',
'XAUR',
'DOGE'
];
$repl = [
'USD ',
'BTC ',
'DASH ',
'LTC ',
'SC ',
'STEEM ',
'WAVES ',
'SNGLS ',
'1ST ',
'BQX ',
'ETH ',
'PTOY ',
'XAUR ',
'DOGE '
];
$input = [
"BTCUSD",
"DASHBTC",
"DOGEUSD",
"LTCBTC",
"LTCUSD",
"SCBTC",
"STEEMBTC",
"WAVESBTC",
"SNGLSBTC",
"1STBTC",
"DASHUSD",
"BQXETH",
"PTOYETH",
"XAURETH",
"BTCUSDT",
];
$new = str_replace($currencies, $repl, $input);
Foreach($new as &$item){
$item = substr($item, 0, strpos($item, " "));
}
Var_dump($new);
https://3v4l.org/QDMjS

Related

Regex for splitting apparel sizes

I have the following input (only for example, real input contains much more crazy data)
$values = [
'32/34, 36/38, 40/42, 44/46',
'40/42/44/46/48',
'58/60',
'39-42',
'40-50-60',
'24-25,26,28,30',
'36 40,5 44',
];
and want to split it by separators like / or , but keep pairs of values. This should be done only, if separator does not occur multiple times, so the result should look like:
'32/34, 36/38, 40/42, 44/46'
=> [ '32/34', '36/38', '40/42', '44/46' ]
'40/42/44/46/48'
=> [ '40', '42', '44', '46', '48' ]
'58/60'
=> [ '58/60' ]
'39-42'
=> [ '39-42' ]
'40-50-60'
=> [ '40', '50', '60' ]
'24-25,26,28,30'
=> [ '24-25', '26', '28', '30' ]
'36 40,5 44'
=> [ '36', '40,5', '44' ]
What I have so far is
$separator = '^|$|[\s,\/-]';
$decimals = '\d+(?:[,.][05])?';
foreach ($values as $value) {
preg_match_all('/' .
'(?<=' . $separator . ')' .
'(?:' .
'(?P<var1>(' . $decimals . ')[\/-](?-1)|(?-1))' .
')(?=' . $separator . ')' .
'/ui', $value, $matches);
print_r($matches);
}
But this fails for 40/42/44/46/48 which returns
[var1] => Array
(
[0] => 40/42
[1] => 44/46
[2] => 48
)
But each number should be returned separately. Modifying regex to '(?P<var1>(' . $decimals . ')([\/-])(?-2)|(?-2))(?!\3)' is better, but still returns wrong result
[var1] => Array
(
[0] => 40
[1] => 42
[2] => 44
[3] => 46/48
)
How should the correct regex look like?
As stated in comments above, I know that a 100% match is not possible, because of user input. But I've found a regex which fits most of my use cases:
(?<=^|$|[\s,\/-])(?:(?P<var1>(?<![\/-])(?!(?:(\d+(?:[,.][05])?)[\/-]){2}(?-1))(\d+(?:[,.][05])?)[\/-](?-1)|(?-1)))(?=^|$|[\s,\/-])
See https://regex101.com/r/q3YSa7/1

How to lowercase string with special characters?

I have this array in PHP:
$weekdays = array(
"mandag" => 1,
"tirsdag" => 2,
"onsdag" => 3,
"torsdag" => 4,
"fredag" => 5,
"lørdag" => 6,
"søndag" => 7);
The function gets the day with random formats like all uppercase or one letter uppercase, I'm doing an strtolower from the variable and then comparing it with the array.
The problem comes here, when I do strtolower on the var with a special character like this one ø from søndag and lørdag, it doesn't recognize the string. How can I change the string to strtolower without modifying the special character?
Try mb_strtolower
$weekdays = array("Mandag" => 1, "Tirsdag" => 2, "Onsdag" => 3, "Torsdag" => 4, "Fredag" => 5, "Lørdag" => 6, "Søndag" => 7);
$weekdays = array_combine(
array_map('mb_strtolower', array_keys($weekdays)),
$weekdays
);
var_dump($weekdays);
...or if you want to check a specific item in the array you can simply run mb_strtolower($item, 'UTF-8') on it.
$happyDay = "SøndAg";
echo $happyDay . ' -> ' . mb_strtolower($happyDay, 'UTF-8');

need to array display in specific format in php

Capture the 'p_data' values into key/pairs and return as table
i try to array display in table format please help me.
$diskspace = array (
'S' =>
array ('DISK-FREE' =>
array (
'name' => 'S',
'desc' => 'FREE',
'p_data' => '\'C:\\ %\'=19%;99;95 \'C:\\\'=17B;3;1073741824;0;21476171776 \'D:\\ %\'=63%;99;99 \'D:\\\'=80B;3;1073741824;0;214753800192 \'E:\\ %\'=91%;99;98 \'E:\\\'=58B;3;1073741824;0;64420311040',),
),
'T' =>
array ('DISK-FREE' =>
array ('name' => 'T',
'desc' => 'FREE',
'p_data' => '\'C:\\ %\'=11%;99;95 \'C:\\\'=15B;3;1073741824;0;21476171776 \'D:\\ %\'=18%;99;99 \'D:\\\'=62B;3;1073741824;0;214753800192',),
),
'P' =>
array ('DISK-USED' =>
array ('name' => 'P',
'desc' => 'FREE',
'p_data' => '\'G:\\ %\'=19%;99;95 \'G:\\\'=92B;3;1073741824;0;21476171776',),
),
);
HTML Output
name, diskname, disk-size, disk-percentage
S, C:\, 17B, 19%
S, D:\, 80B, 63%
S, E:\, 58B, 91%
T, C:\, 15B, 11%
T, D:\, 62B, 18%
P, G:\, 92B, 19%
Use this code to extract All xxB and xx% data and try to display them drom array, make sure you try this for S , T , ... or other data in array
function Disk2Array($Name , $array) {
return $array[$Name]['DISK-FREE']['p_data'];
}
$precent = '/[0-9][0-9]\%/';
$size = '/[0-9][0-9][B]/';
preg_match_all($size , Disk2Array('S' , $diskspace) , $match);
print_r($match);
preg_match_all($precent , Disk2Array('S' , $diskspace) , $match);
print_r($match);
You have not specified what you wanted to put into the specific attributes as values and I am reluctant to guess it, so I will assume that you have a function which handles a passed p_data and returns the array you need to have.
function handlePValue($p_value) {
//your code here to return the desired value
}
$p_dataValues = array();
foreach ($diskspace as $element) {
$p_dataValues[] = handlePValue($element["p_data"]);
}

get integer / float from string in PHP

I ran into an issue with a data feed I need to import where for some reason the feed producer has decided to provide data that should clearly be either INT or FLOAT as strings-- like this:
$CASES_SOLD = "THREE";
$CASES_STOCKED = "FOUR";
Is there a way in PHP to interpret the text string as the actual integer?
EDIT: I should be more clear-- I need to have the $cases_sold etc. as an integer-- so I can then manipulate them as digits, store in database as INT, etc.
Use an associative array, for example:
$map = array("ONE" => 1, "TWO" => 2, "THREE" => 3, "FOUR" => 4);
$CASES_SOLD = $map["THREE"]; // 3
If you are only interested by "converting" one to nine, you may use the following code:
$convert = array('one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
'six' => 6,
'seven' => 7,
'eight' => 8,
'nine' => 9
);
echo $convert[strtolower($CASES_SOLD)]; // will display 3
If you only need the base 10 numerals, just make a map
$numberMap = array(
'ONE' => 1
, 'TWO' => 2
, 'THREE' => 3
// etc..
);
$number = $numberMap[$CASES_SOLD];
// $number == 3'
If you need something more complex, like interpreting Four Thousand Two Hundred Fifty Eight into 4258 then you'll need to roll up your sleeves and look at this related question.
Impress your fellow programmers by handling this in a totally obtuse way:
<?php
$text = 'four';
if(ereg("[[.$text.]]", "0123456789", $m)) {
$value = (int) $m[0];
echo $value;
}
?>
You need a list of numbers in english and then replace to string, but, you should play with 'thousand' and 'million' clause where must check if after string 'thousend-three' and remove integer from string.
You should play with this function and try change if-else and add some functionality for good conversion:
I'm writing now a simple code for basic, but you know others what should change, play!
Look at million, thousand and string AND, it should be change if no in string like '1345'. Than replace with str_replace each of them separaterly and join them to integer.
function conv($string)
{
$conv = array(
'ONE' => 1,
'TWO' => 2,
'THREE' => 3,
'FOUR' => 4,
'FIVE' => 5,
'SIX' => 6,
'SEVEN' => 7,
'EIGHT' => 8,
'NINE' => 9,
'TEN' => 10,
'ELEVEN' => 11,
'TWELVE' => 12,
'THIRTEEN' => 13,
'FOURTEEN' => 14,
'FIFTEEN' => 15,
'SIXTEEN' => 16,
'SEVENTEEN' => 17,
'EIGHTEEN' => 18,
'NINETEEN' => 19,
'TWENTY' => 20,
'THIRTY' => 30,
'FORTY' => 40,
'FIFTY' => 50,
'SIXTY' => 60,
'SEVENTY' => 70,
'EIGTHY' => 80,
'NINETY' => 90,
'HUNDRED' => 00,
'AND' => '',
'THOUSAND' => 000
'MILLION' => 000000,
);
if (stristr('-', $string))
{
$val = explode('-', $string);
#hardcode some programming logic for checkers if thousands, should if trim zero or not, check if another values
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
else
{
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
}
Basically what you want is to write a parser for the formal grammar that represents written numbers (up to some finite upper bound). Depending on how high you need to go, the parser could be as trivial as
$numbers = ('zero', 'one', 'two', 'three');
$input = 'TWO';
$result = array_search(strtolower($input), $numbers);
...or as involved as a full-blown parser generated by a tool as ANTLR. Since you probably only need to process relatively small numbers, the most practical solution might be to manually hand-code a small parser. You can take a look here for the ready-made grammar and implement it in PHP.
This is similar to Converting words to numbers in PHP
PHP doesn't have built in conversion functionality. You'd have to build your own logic based on switch statements or otherwise.
Or use an existing library like:
http://www.phpclasses.org/package/7082-PHP-Convert-a-string-of-English-words-to-numbers.html

Parsing a malformed CSV file

How can I parse a CSV like this one in PHP (there's a double quote near value 8)?
"03720108";"value 8"";"";"219";"03720108";"value";"value";"value";"";"";"";"";"";"";"value";"";"";"value";"value";
I tried with fgetscv($pointer, 4096, ';', '"');
Your data seems to be malformed starting at the prior line. You have an opening quote with no closing quote.
Yes. Notice the extra quote.
"value 8"";
You might still be able to parse this string, though:
$str = '"03720108";"value 8"";"";"219";"03720108";"value";"value";"value";"";"";"";"";"";"";"value";"";"";"value";"value";';
$parsed = array_map(
function( $str ) { return substr($str, 1, -1); },
explode(';', $str)
);
var_export($parsed);
/*
array (
0 => '03720108',
1 => 'value 8"',
2 => '',
3 => '219',
4 => '03720108',
5 => 'value',
6 => 'value',
7 => 'value',
8 => '',
9 => '',
10 => '',
11 => '',
12 => '',
13 => '',
14 => 'value',
15 => '',
16 => '',
17 => 'value',
18 => 'value',
19 => false,
)
*/
Things get a bit more complicated, though, if there are elements that contain a ; character (normally would be escaped by enclosing the value in quotes... d'oh!), and the above code assumes that you only need to parse a single line (though if you are using fgets() to read the input stream, you should be OK).

Categories