I'm reformulating one of my old programs and using TextCrawler to automate text replacements in several code files, but I'm struggling to make the following change:
I need to find all 'text' functions (example):
$object->text('TRANSLATE_KEY_A')
$object->text('TRANSLATE_KEY_B')
...
and replace them with (example):
__('RETURNED_TEXT_FROM_TRANSLATE_KEY_A', TEXT_DOMAIN)
__('RETURNED_TEXT_FROM_TRANSLATE_KEY_B', TEXT_DOMAIN)
...
Where RETURNED_TEXT_FROM_TRANSLATE_KEY_X are set with the 'text' array's key in another code file
array_push($text, array('key' => 'TRANSLATE_KEY_A',
'extras' => '',
'text' => 'Translated Text A'));
array_push($text, array('key' => 'TRANSLATE_KEY_B',
'extras' => '',
'text' => 'Translated Text B'));
The final result should be:
$object->text('TRANSLATE_KEY_A')
$object->text('TRANSLATE_KEY_B')
...
replaced with
__('Translated Text A', TEXT_DOMAIN)
__('Translated Text B', TEXT_DOMAIN)
...
There are over 1500 of these :(
Is it possible to achieve this with regular expression in TextCrawler, and how? Or any other idea? Thanks
If you want to use a php array to provide the replacement data it is probably best to just use php itself for the task.
Example script.php:
// your $text array
$text = array();
array_push($text, array(
'key' => 'TRANSLATE_KEY_A',
'extras' => '',
'text' => 'Translated Text A')
);
array_push($text, array(
'key' => 'TRANSLATE_KEY_B',
'extras' => '',
'text' => 'Translated Text B')
);
...
// create a separate array from your $text array for easy lookup
$data_arr = array();
foreach ($text as $val) {
$data_arr[$val['key']] = $val['text'];
}
// your code file, passed as first argument
$your_code_file = $argv[1];
// open file for reading
$fh = fopen($your_code_file, "r");
if ($fh) {
while (($line = fgets($fh)) !== false) {
// check if $line has a 'text' function and if the key is in $data_arr
// if so, replace $line with the __(...) pattern
if (preg_match('/^\$object->text\(\'([^\']+)\'\)$/', $line, $matches)
&& isset($data_arr[$matches[1]])) {
printf("__('%s', TEXT_DOMAIN)\n", $data_arr[$1]);
} else {
print($line);
}
}
fclose($fh);
} else {
print("error while opening file\n");
}
Call:
php script.php your_code_file
Just add functionality to iterate over all of your code files and write to the corresponding output files.
Related
I have a varying array for a playlist, containing media/source URLs for each item. Like this:
$playlist = array(
array(
"title" => "something",
"sources" => array(
array(
"file" => "https://url.somedomain.com/path/file1.mp3"
)
),
"description" => "somedesc",
"image" => "http://imagepath/",
"file" => "https://url.somedomain.com/path/file1.mp3"
),
array(
"title" => "elsewaa",
"sources" => array(
array(
"file" => "https://url.somedomain.com/someother/file2.mp3"
)
),
"description" => "anotherdesc",
"image" => "http://someotherimagepath/",
"file" => "https://url.somedomain.com/someother/file2.mp3"
)
);
How do I find and replace the values in the file keys to 'randomise' the choice of subdomain?
For example, if the file key contains url.foo.com, how do I replace the url.foo.com portion of the array value with either differentsubdomain.foo.com or anotherplace.foo.com or someotherplace.foo.com?
I was kindly offered a solution for a single string in this question/answer that used str_replace (thanks Qirel!), but I need a solution that tackles the above array configuration specifically.
All the nesting in the array does my head in!
Is it possible to adapt Qirel's suggestion somehow?
$random_values = ['differentsubdomain.foo.com', 'anotherplace.foo.com', 'someotherplace.foo.com'];
$random = $random_values[array_rand($random_values)];
// str_replace('url.foo.com', $random, $file);
If you are just asking how to access members in nested arrays, I think you want this:
$random_values = ['differentsubdomain.foo.com', 'anotherplace.foo.com', 'someotherplace.foo.com'];
// Iterate through the array, altering the items by reference.
foreach ($playlist as &$item) {
$random_key = array_rand($random_values);
$new_domain = $random_values[$random_key];
$item['file'] = str_replace('url.foo.com', $new_domain);
$item['sources'][0]['file'] = str_replace('url.foo.com', $new_domain);
}
Here's an example using recursion to replace the subdomains in any keys named file with a random one.
function replaceUrlHost(&$array, $hostDomain, $subdomains)
{
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = replaceUrlHost($value, $hostDomain, $subdomains);
continue;
}
if ($key !== 'file') {
continue;
}
$hostname = parse_url($value, PHP_URL_HOST);
if (strpos($hostname, $hostDomain) === false) {
continue;
}
$array[$key] = str_replace(
$hostname,
$subdomains[array_rand($subdomains)] . '.' . $hostDomain,
$value
);
}
return $array;
}
// usage
$subdomains = ['bar', 'baz', 'bing', 'bop'];
$out = replaceUrlHost($playlist, 'somedomain.com', $subdomains);
I am trying to put my text file into an array..
my text file content is like this:
TP-Link|192.168.1.247|CHANNEL 02|warehouse
Ruckus|192.168.1.248|CHANNEL 03|entrance
anyone can help me to make the output looks like this:
$servers = array(
array(
'name' => 'TP-Link',
'ip' => '192.168.1.247',
'channel' => 'CHANNEL 02',
'location' => 'warehouse',
),
array(
'name' => 'Ruckus',
'ip' => '192.168.1.248',
'channel' => 'CHANNEL 03',
'location' => 'entrance',
),
);
thanks in advance..
this is my code:-
$file="config/data.txt";
$fopen = fopen($file, r);
$fread = fread($fopen,filesize($file));
fclose($fopen);
$remove = "\n";
$split = explode($remove, $fread);
$servers[] = null;
$tab = "|";
foreach ($split as $string)
{
$row = explode($tab, $string);
array_push($servers,$row);
}
the problem is it outputs a multidimensional without array names..
and i am not familiar in multidimensional array..
You can do it like below:-
<?php
$data = file("your text-file path"); // file() read entire file into array
// now your array looks like below:-
$array = array('TP-Link|192.168.1.247|CHANNEL 02|warehouse',
'Ruckus|192.168.1.248|CHANNEL 03|entrance'); // comment this array line while using the code
$keys = array('name','ip','channel','location');
$final_array = array();
foreach ($array as $ar){
$explode = explode('|',$ar);
$final_array[] = array_combine($keys,$explode);
}
echo "<pre/>";print_r($final_array);
Output:-https://eval.in/734221
You can do something like this. Check out explode and fgets
<?php
$servers_array = array();
$handle = #fopen("inputfile.txt", "r");
if ($handle) {
while (($buffer = fgets($handle)) !== false) {
$line = explode("|", $buffer);
$servers_array[] = array(
"name" => $line[0],
"ip" => $line[1],
"channel" => $line[2],
"location" => $line[3],
)
}
fclose($handle);
}
?>
So if you have a text file consisting of the following, just use the following code to get the output that you want:
<?php
$str="TP-Link|192.168.1.247|CHANNEL 02|warehouse
Ruckus|192.168.1.248|CHANNEL 03|entrance";
echo '<pre>';
$sections=explode("\n",$str);
print_r($sections);
$finalArray=array();
foreach($sections as $line){
$finalArray[]=explode("|",$line);
}
print_r($finalArray);
?>
NOTE: $str is the text that you get from the text file
I have this file, I cant figure out how to parse this file.
type = 10
version = 1.2
PART
{
part = foobie
partName = foobie
EVENTS
{
MakeReference
{
active = True
}
}
ACTIONS
{
}
}
PART
{
part = bazer
partName = bazer
}
I want this to be a array which should look like
$array = array(
'type' => 10,
'version' => 1.2,
'PART' => array(
'part' => 'foobie',
'partName' => 'foobie,
'EVENTS' => array(
'MakeReference' => array(
'active' => 'True'
)
),
'ACTIONS' => array(
)
),
'PART' => array(
'part' => 'bazer',
'partName' => 'bazer'
)
);
I tried with preg_match but that was not a success.
Any ideas?
Why not use a format that PHP can decode natively, like JSON?
http://php.net/json_decode
$json = file_get_contents("filename.txt");
$array = json_decode($json);
print_r($array);
Here is my approach.
First of all change Im changing the { to the line before.
Thats pretty easy
$lines = explode("\r\n", $this->file);
foreach ($lines as $num => $line) {
if (preg_match('/\{/', $line) === 1) {
$lines[$num - 1] .= ' {';
unset($lines[$num]);
}
}
Now the input looks like this
PART {
part = foobie
Now we can make the whole thing to XML instead, I know that I said a PHP array in the question, but a XML object is still fine enough.
foreach ($lines as $line) {
if (preg_match('/(.*?)\{$/', $line, $matches)) {
$xml->addElement(trim($matches[1]));
continue;
}
if (preg_match('/\}/', $line)) {
$xml->endElement();
continue;
}
if (strpos($line, ' = ') !== false) {
list($key, $value) = explode(' = ', $line);
$xml->addElementAndContent(trim($key), trim($value));
}
}
The addElement, actually just adds a to a string
endElement adds a and addElementAndContent doing both and also add content between them.
And just for making the whole content being a XML object, im using
$xml = simplexml_load_string($xml->getXMLasText());
And now $xml is a XML object, which is so much easier to work with :)
I'm creating a "quote database" for a TV show I'm a fan of, and I'm rewriting parts of it I don't particularly like. I came across my function to parse the data holding the quote and characters into an array that I can easily loop through and display. One of the features of the site is that you can have a single quote (one-liner) or a conversation between several characters. Right now I'm storing single quotes like this:
[charactername]This is my witty one-liner.
And conversations follow the same pattern:
[characternameone]How's the weather?
[characternametwo]Pretty good, actually.
And so on. Here's the aforementioned parsing function:
function parse_quote($text)
{
// Determine if it's a single or convo
if ( strpos($text, "\n") != false )
{
// Convo
// Let's explode into the separate characters/lines
$text = explode("\n", $text);
$convo = array();
// Parse each line into character and line
foreach ( $text as $part )
{
$character = substr($part, 1, strpos($part, ']') - 1);
$line = substr($part, strlen($character) + 2);
$convo[] = array(
'character' => $character,
'line' => $line
);
}
return array(
'type' => 'convo',
'quote' => $convo
);
}
else
{
// Single
// Parse line into character and line
return array(
'type' => 'single',
'quote' => array(
'character' => substr($text, 1, strpos($text, ']') - 1),
'line' => substr($text, strlen(substr($text, 1, strpos($text, ']') - 1)) + 2)
)
);
}
}
It works as expected, but I can't help but think there's a better way to do this. I'm horrible with regular expressions, which I assume would come in at least somewhat handy in this situation. Any advice, or improvements?
Personally, I would change your data storage method. It would be much easier to deal with a serialized or JSON encoded string.
Instead of
[characternameone]How's the weather?
[characternametwo]Pretty good, actually.
you would have
array(
[0] => {
'name' => "characternameone",
'quote' => "How's the weather?"
},
[1] => {
'name' => "characternametwo",
'quote' => "Pretty good, actually"
}
)
Then when you read it out, there isn't any parsing.
function display_quote($input)
{
for ($i=0, $n=count($input); $i<$n; $i++) {
$quote = $input[$i];
if ( $i > 0 ) echo "\n";
echo $quote['name'] . ': ' . $quote['quote'];
}
}
Instead of
$character = substr($part, 1, strpos($part, ']') - 1);
$line = substr($part, strlen($character) + 2);
$convo[] = array(
'character' => $character,
'line' => $line
);
you could try
preg_match('#\[([^\]]+)\](.*)#ism', $part, $match);
$convo[] = array(
'character' => $match[1],
'line' => $match[2]
);
HTH
how can i make this code display $anchor with spaces. I would have Text Anchor1 and Text Anchor two insitead of TextAnchor1 and TextAnchor2. Thank you
$currentsite = get_bloginfo('wpurl');
$sites = array(
'TextAnchor1' => 'http://www.mysite1.com',
'TextAnchor2' => 'http://www.mysite2.com'
);
foreach($sites as $anchor => $site)
{
if ( $site !== $currentsite ){echo '<li>'.$anchor.'</li>';}
}
So, as you $anchor values probably aren't hard-coded, I assume what you really need is a function that takes a string as an argument and inserts spaces before any capital letters or numbers.
function splitWords($s){
return trim(preg_replace('/([A-Z0-9])/', ' \1', $s));
}
Later, when writing output, instead of $anchor, you can use splitWords($anchor).
$sites = array(
'Text Anchor 1' => 'http://www.mysite1.com',
'Text Anchor 2' => 'http://www.mysite2.com'
);
Ooh, ooh, my turn.
$sites = array(
'Text Anchor 1' => 'http://www.mysite1.com',
'Text Anchor 2' => 'http://www.mysite2.com'
);
Just change to:
$sites = array(
'Text Anchor' => 'http://www.mysite1.com',
'My Text Anchor' => 'http://www.mysite2.com'
);