regex for changing array() to [] using atom - php

I am wanting to update my php script as a project (globally) and change array(elements); to [elements];
Using atom i have already ran the update for just the init of arrays and have already changed array(); to []; however this just takes care of the empty array initialization codes.
The challenge now is to change arrays that actually have elements in them from () to []
For example the arrays could be in several formats
array('content',number content,'content');
or
array(
'content',
array(
number content,'content'
)
);
or any variation of the number of levels.
I have broken it down this way but i dont know how to do the regex.,
Find every occurance of array(
- replace with [
Find the associated close of that array );
-replace with ];
Find every array( inside another which is array(
-replace with [
Find the associated close of each of those arrays that are inside another array ); or just ),
- replace with ]; or ],
I think that should cover it.... is the regex going to be impossible to do?
thanks

Seeing, that you are willing to do some manual repairs afterwards and that the solution suggested in my comment is of interest to you I now put it in "proper" answer form. This is easier to edit and to discuss. As said before, this is only a "workaround", as we are not really parsing the text in the sense of really understanding it syntactically. However, when you apply the following Regexp
\barray\(([^()]*)\)
repeatedly and replace it with
[$1]
(yes, I left out the "array" in front of "["!) you might have a chance of doing what you want.
I put a \b in front of the Regexp to make it look for a word boundary. This way we exclude text fragments like is_array() or myarray() from being changed.

Related

Is there a possible way to use multidimensional arrays to replace words in a string using str_replace() and the array() function?

Note: I have seen this question here, but my array is completely different.
Hello everyone. I have been trying to make a censoring program for my website. What I ended up with was:
$wordsList = [
array("frog","sock"),
array("Nock","crock"),
];
$message = str_replace($wordsList[0], $wordsList[1], "frog frog Nock Nock");
echo $message;
What I am trying to do is replace "frog" with "sock" using multidimentional arrays without typing all of the words out in str_replace();
Expected Output: "sock sock crocs crocs"
However, when I execute it, for some unknown reason it doesn't actually replace the words, without any errors. I think it's a rookie mistake that I made, but I have searched and have not found any documentation on using a system like this. Please help!
You need to change the structure of your wordsList array.
There are two structures that will make it easy:
As key/value pairs
This would be my recommendation since it's super clear what the strings and their replacements are.
// Store them as key/value pairs with the search and replacement strings
$wordsList = [
'frog' => 'sock',
'Nock' => 'crock',
];
$message = str_replace(
array_keys($wordsList), // Get all keys as the search array
$wordsList, // The replacements
"frog frog Nock Nock"
);
Demo: https://3v4l.org/WsUdn
As a multidimensional array
This one requires you to add the search/replacement values in the same order, which can be hard to read when you have a few different strings.
$wordsList = [
['frog', 'Nock'], // All search strings
['sock', 'crock'], // All replacements
];
$message = str_replace(
$wordsList[0], // All search strings
$wordsList[1], // The replacements strings
"frog frog Nock Nock"
);
Demo: https://3v4l.org/RQjC6
If you can't change the original array, then create a new array with the correct structure since that won't work "as is".

Efficient way to capture "variations" or "combinations" ore "aliases" for switch-case argument(s) in PHP

I am pretty sure this challenge has been solved by someone already but even searching with different words, I could not find a solution for this problem:
I try to give users the possibility to run certain functions of a class based on an argument like
service_class::do_this( "selection-argument" );
but the user shall be able to use "clear words" as well as "aliases" and even "well known" abbreviations or synonyms.
I use switch-case construction to call the "real" function.
Example: To get the contens of a folder, The user can use "getdir", "dir", "Directory", "getfolder", "getcontent", "content", "d-cont" and a number of more other "matching words" to start the function(s) underlaying and getting back the very same result.
Capture-ing lowercase/uppercase is simple. What I search for is an efficient way to capture all possible "variations" - that are, of course different number of variations for different functions called.
At the moment I use multiple "case "": lines after each other, but that makes the code quite long, and further I would like the user to be able to "enahnce" the recognition set for a certain function.
That's why I thought about "stripos" to determine first what "internal word" to use and only then run into the switch-case construction.
Anyone had that issue and can direct me to a "good and efficient" solution?
Seems that Stck-exchange itself had a similar challenge (https://codereview.stackexchange.com/tags/php/synonyms) ... maybe I can simply re-use the underlying code?
Thanks in advance and sorry if I overlooked a solution already posted.
You could use a database or array. Let's do the latter. So to determine whether an user wants to get a directory you would define an array like this:
$getDirVariants = ['getdir',
'dir',
'directory',
'getfolder',
'getcontent',
'content',
'd-cont'];
It is easy to add more of these arrays. To test the query word you would do:
$queryWord = strtolower($queryWord);
if (in_array($queryWord, $getDirVariants)) service_class::getDir(<arguments>);
elseif (in_array($queryWord, $deleteVariants)) service_class::delete(<arguments>);
You can easily add to the arrays or make it a 2D array to contain more commands. That array could also be placed in a database.
Especially when there are many commands, with many variants, a database will be the better solution, because you can find the query word with one database query.
There's a variation I can think of that will also simplify the code when there are many commands. You could use an associative array to find the command:
$commandVariants = ['getdir' => 'getdir',
'dir' => 'getdir',
'directory' => 'getdir',
'getfolder' => 'getdir',
'getcontent' => 'getdir',
'content' => 'getdir',
'd-cont' => 'getdir',
'delete' => 'delete',
'del' => 'delete',
'remove' => 'delete',
'unlink' => 'delete'];
$queryWord = strtolower($queryWord);
if (isset($commandVariants[$queryWord])) {
$command = $commandVariants[$queryWord];
service_class::$command(<arguments>);
}
else echo "I don't recognize that command.";
This uses a variable identifier.

PHP adding or subtracting elements from array

I have a query string. For example:
?filters=1,2,3,4
It gets turned into an array:
$filters = explode(',', $_GET['filters']);
You could push a new value on
$filters = array_push($filters, $new->filter);
Then turn it into the query string
http_build_query($filters);
Or, remove a value
$filters = array_diff($filters, [$new->filter]);
Then turn it into the query string
http_build_query($filters);
I'm looking for an elegant solution to remove the item if it already exists or to add the item if it does not exist. Alternative solutions are also welcome.
Thank you.
Hopefully I'm understanding you correctly "I'm looking for an elegant solution to remove the item if it already exists or to add the item if it does not exist.". Also, not sure if it is elegant but may spark other ideas:
$filters = in_array($new->filter, $filters) ?
array_diff($filters, [$new->filter]) :
array_merge($filters, [$new->filter]);
That's about as elegant as it gets, unless you want to use PHP's array notation "hack", e.g.
?filters[]=1&filters[]=2&filters[]=3&etc...
^^---
That'd save you the explode() stage and gives you the ability to treat $_GET['filters'] as an array directly, but at the cost of an uglier/longer URL.
Perhaps you should write 2 functions, "remove" and "add", which would each loop through the array looking for the value in question. Then the remove function could remove it, and the add function could add it. The functions themselves would not be so elegant, but using them would be simple elsewhere in your code.

change order of array elements in php file

Not sure about how to title this post.
I just inherited a set of internationalization documents, each containing an array of key value pairs. I recognize the methodology is not ideal, it is however, what I'm stuck with given my role, the time and resources I have available. These lists were created by hand and items were constantly being added haphazardly to keep up with demand. The examples below are simplified, there are ~21 language files, each with 100+ entries.
The array from one file will have elements something like the below:
'download_high' => 'Vysoké',
'download_low' => 'Nízké',
'download_med' => 'Strední',
'download_video' => 'Stáhnout video',
While another file will have something like the following:
'download_video' => 'Descargar Video',
'download_high' => 'Alta',
'download_med' => 'Media',
'download_low' => 'Baja',
For the most part, the elements are ordered consistently, but there are plenty of exceptions and it complicates maintaining the files. I was wondering if there's a way to make the order / formatting of these arrays consistent either via an IDE or notepad++ plugin, etc. I don't want to order them alphabetically necessarily as there are logical groupings that won't translate well to alphabetical sorting since only some of the variables are namespaced. Doing it by hand is almost out of the question, but it would be nice if there were some way to specify an order and have some kind of text manipulation tool batch process the files. I'm not all that familiar with php, so I don't know that it would be worth it for me to do this via code unless it's very simple.
PHP has a function called var_export. You could run the code and then print it with the function.
Personally, I would run some regex in notepad++ to do it.
Edit: In notepad++, you can do a find/replace with regex.
In the "Find what" field, put \s*'(.+?)'\s*=>\s*'(.+?)'\s*(?:(,)|\s*$)\s*
In the "Replace with" field, put '$1' => '$2'$3\n
This will turn something like:
'download_high' =>  'Vysoké',
'download_low'=>
'Nízké',
'download_med'
=>
'Strední'
,
'download_video' => 'Stáhnout video',
'filter_by' => 'Filtrovat podle'
,
'footer_contact' => 'Kontakt'
into
'download_high' => 'Vysoké',
'download_low' => 'Nízké',
'download_med' => 'Strední',
'download_video' => 'Stáhnout video',
'filter_by' => 'Filtrovat podle',
'footer_contact' => 'Kontakt'
*note: This is written with the assumption that all keys and values use single quotes and that neither keys nor values have any escaped single quotes inside.
Given the situation I'd do it semi-automatically on an as-needed basis. That is, it sounds to me like you're charged with maintaining these files, and it's in the maintenance that the sorting becomes an issue.
For each language file formatted like:
<?php
$something = array(
'download_video' => 'Descargar Video',
'download_high' => 'Alta',
...
'download_med' => 'Media',
'download_low' => 'Baja',
);
Issue a sort lang.es.php command in bash, or via however you prefer to sort something.
Open the file for editing.
Delete the array declaration.
Copy/paste the sorted lines from #1.
Honestly, it was a super bad idea for your predecessor to effectively hard-code something like this. It would be much better if this were stored via CSV, XML, pg/mySQL, etc where you could at least invoke an editor that understands the data format.
i wouldn't suggest using arrays and php files etc if you are going to have a continuously growing list. take the couple minutes now to set up mysql and pull from a database with your desired parameters. NEAT, FAST, EFFECIENT AND SCALABLE.
My suggestion would be to simply build a script to load all those arrays into a database where they can be maintained more easily. Of course you would need to make sure you database table/fields were set up for UTF-8 character sets and collations.
Am I correct in understanding that you have already gotten your data into PHP arrays? At this point you could just do this to sort the keys. This would make the ordering consistent:
ksort($array);

How to choose between explode and regex

My string is to contain some "hotkeys" of the form [hotkey]. For example:
"This is a sample string [red] [h1]"
When I process this string with a php function, I'd like function to output the original string as follows;
<font color='red'><h1>This is a sample string</h1></font>
I'd like to use this function purely for convenience purposes easing some typing. I may use a font tag or div or whatever, let's not get into that. The point is this; a hotkey will cause the original string to be wrapped into
<something here>original string<and something there>
So the function first needs to determine if there are any hotkeys or not. That's easy; just check to see if there is any existence of [
Then we will need to process the string to determine which hotkeys exist and get into the biz logic as to which wrappers to be deployed.
and finally we will have to clean the original string from the hotkeys and return the results back.
My question is if there is a regex that would make this happen more effectively then the following parsing method that I am planning of implementing the function as.
step 1
explode the string into an array using the [ delimiter
step 2
go thru each array element to see if the closing ] is present and it forms one of the defined hotkeys, and if so, do the necessary.
Obviously, this method is not using any regex power. I'm wondering if regex could be of help here. Or, any better way to do it you may suggest?
If [ and ] are the only delimeters you need to worry about, you could probably use strtok
I don't speak english well but I saw your example :
"This is a sample string [red] [h1]"
<font color='red'><h1>This is a sample string</h1></font>
If I were you :
$red = substr( $chaine, strpos($chaine, '['), strpos($chaine, ']') );

Categories