Retrieve text from XML? - php

I want to get all words between XML tags from a array and the current outcome is:
Notice: Array to string conversion in ........ on line 84
Result is: Array
if(isset($_POST['send']))
{
echo "sync is started <br>";
$handle = fopen("XML/$file_name", "r");
if ($handle)
{
while (($line = fgets($handle)) !== false)
{
$keywords=array("series_title","series_type","series_episodes");
for ($i=0; $i < 3; $i++)
{
$pattern = "/<$keywords[$i]>(.*?)<\/keywords[$i]>/";
preg_match($pattern, $line, $matches);
echo "result is: " . $matches . "<br>";
}
}
}
else
{
$upload_text = "error";
}
$upload_text ="finished";
fclose($handle);
//unlink('XML/' . $file_name);
}

You should use SimpleXML to read the XML instead. Here is an example:
<?php
$string = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<myanimelist>
<anime>
<series_animedb_id>1143</series_animedb_id>
<series_title><![CDATA[.hack//Intermezzo]]></series_title>
<series_type>Special</series_type>
<series_episodes>1</series_episodes>
</anime>
<anime>
<series_animedb_id>299</series_animedb_id>
<series_title><![CDATA[.hack//Liminality]]></series_title>
<series_type>OVA</series_type>
<series_episodes>4</series_episodes>
</anime>
</myanimelist>
XML;
$result = simplexml_load_string($string);
foreach ($result->anime as $anime)
{
echo trim($anime->series_title), "\n";
echo $anime->series_type, "\n";
echo $anime->series_episodes, "\n";
echo "==========================\n\n";
}
Live DEMO.
In your case you would use simplexml_load_file, so your code would look like this:
<?php
$result = simplexml_load_file('your_file_path_here.xml');
foreach ($result->anime as $anime)
{
echo trim($anime->series_title), "\n";
echo $anime->series_type, "\n";
echo $anime->series_episodes, "\n";
}

Well, as you can read in the Official PHP Documentation, the optional preg_match third argument will be an array
matches
If matches is provided, then it is filled with the results of search.
$matches[0] will contain the text that matched the full pattern,
$matches1 will have the text that matched the first captured
parenthesized subpattern, and so on.
So simply change your :
echo "result is: " . $matches . "<br>";
to :
echo "result is: " . $matches[1] . "<br>";
Hope it helps

The value returned in the $matches parameter of the preg_match function is an array, the first element of which is the entire match, and the following elements are the capture groups (the parts between parentheses).
So, in your code, you'd only be interested in $matches[1]:
echo "result is: $matches[1]<br>";

Related

Find words in text, php

How to resolve this problem:
Write a PHP program that finds the word in a text.
The suffix is separated from the text by a pipe.
For example: suffix|SOME_TEXT;
input: text|lorem ips llfaa Loremipsumtext.
output: Loremipsumtext
My code is this, but logic maybe is wrong:
$mystring = fgets(STDIN);
$find = explode('|', $mystring);
$pos = strpos($find, $mystring);
if ($pos === false) {
echo "The string '$find' was not found in the string '$mystring'.";
}
else {
echo "The string '$find' was found in the string '$mystring',";
echo " and exists at position $pos.";
}
explode() returns an array, so you need to use $find[0] for the suffix, and $find[1] for the text. So it should be:
$suffix = $find[0];
$text = $find[1];
$pos = strpos($text, $suffix);
if ($pos === false) {
echo "The string '$suffix' was not found in '$text'.";
} else {
echo "The string '$suffix' was found in '$text', ";
echo " and exists at position $pos.";
}
However, this returns the position of the suffix, not the word containing it. It also doesn't check that the suffix is at the end of the word, it will find it anywhere in the word. If you want to match words rather than just strings, a regular expression would be a better method.
$suffix = $find[0];
$regexp = '/\b[a-z]*' . $suffix . '\b/i';
$text = $find[1];
$found = preg_match($regexp, $text, $match);
if ($found) {
echo echo "The suffix '$suffix' was found in '$text', ";
echo " and exists in the word '$match[0]'.";
} else {
echo "The suffix '$suffix' was not found in '$text'.";
}

Echo array with string as separator

I have the following code in PHP, which searches a file for lines containing a string:
<?php
echo "Results for: ";
echo ($_POST['query']);
echo "<br><br>";
$file = 'completed.db';
$searchfor = ($_POST['query']);
header('Content-Type: text/plain');
$contents = file_get_contents($file);
$pattern = preg_quote($searchfor, '/');
$pattern = "/^.*$pattern.*\$/m";
if(preg_match_all($pattern, $contents, $matches)){
echo "Found matches:\n";
echo implode("\n", $matches[0]);
}
else{
echo "No matches found";
}
?>
In the line, echo implode("\n", $matches[0]); in echos an array, separated by spaces. If I wanted to separate the items by a different string, say $entry = '<br>', how would you do it?
For example, if $matches was
one
two
three
Then, the command should echo:
one<br>two<br>three<br>
Just add the break tag to the string
echo implode("\n<br>", $matches[0]);
And one more to trail since implode only goes between.
echo "<br>";
The following code simply uses implode with a different first argument, bu also adds the separator to the end (as per specification)
$entry = '<br>';
echo implode($entry, $matches[0]).$entry;

annoying array tags.. want a pretty output

What i'm trying to do is make my output usable for a spreadsheet.
I want each item in the output without array tags or not mashed together but starting with an asterisk and ending with a % sign.
<?php
$file = file_get_contents('aaa.txt'); //get file to string
$row_array = explode("\n",$file); //cut string to rows by new line
$row_array = array_count_values(array_filter($row_array));
foreach ($row_array as $key=>$counts) {
if ($counts==1)
$no_duplicates[] = $key;
}
//do what You want
echo '<pre>';
print_r($no_duplicates);
//write to file. If file don't exist. Create it
file_put_contents('no_duplicates.txt',$no_duplicates);
?>
Maybe this would give you what you want:
$str = "*" . implode("% *", $no_duplicates) . "%";
echo '<pre>';
echo $str;
echo '</pre>';

Indexed substitution within string

I am looking to convert a string with a special HTML tag and parse it accordingly. Below I will show what the original string is followed by what I want the parsed string to be. If someone can direct me towards a proper coding method to make this possible that would be fantastic.
Original String:
$string = '<string 1="Jacob" 2="ice cream">{1} likes to have a lot of {2}.</string>';
Parsed String:
$parsed_string = 'Jacob likes to have a lot of ice cream.';]
EDIT:
I forgot to add that the $string variable may having multiple strings with multiple options, for example the $string variable could be the following:
$string = '<string 1="hot dog">I like to have {1}</string> on <string 1="beach" 2="sun">the {1} with the blazing hot {2} staring down at me.';
I need a solution that can parse the code example above.
EDIT 2:
Here is a sample code I developed that is incomplete and has a few bugs. If there is more than one option e.x. 1='blah' 2='blahblah' it will not parse the second option.
$string = '<phrase 1="Jacob" 2="cool">{1} is {2}</phrase> when <phrase 1="John" 2="Chris">{1} and {2} are around.</phrase>';
preg_match_all('/<phrase ([0-9])="(.*?)">(.*?)<\/phrase>/', $string, $matches);
print $matches[1][0] . '<br />';
print $matches[2][0] . '<br />';
print $matches[3][0] . '<br />';
print '<hr />';
$string = $matches[3][0];
print str_replace('{' . $matches[1][0] . '}', $matches[2][0], $output);
print '<hr />';
print '<pre>';
print_r($matches);
print '</pre>';
As $string is no valid XML (e.g. containing numbers as attribute names), you may try:
$string = '<string 1="Jacob" 2="ice cream">{1} likes to have a lot of {2}.</string>';
$parsed_string = strip_tags($string);
for ($i = 1; $i <= 2; $i++) {
if (preg_match('/' . $i . '="([^"]+)"/', $string, $match))
$parsed_string = str_replace('{' . $i .'}', $match[1], $parsed_string);
}
echo $parsed_string;
UPDATE
Your EDIT switched from having one <string> tag to having multiple <string> tags in the variable now. This one should work for multiples:
$string2 = '<string 1="hot dog">I like to have {1}</string> on <string 1="beach" 2="sun">the {1} with the blazing hot {2} staring down at me.</string>';
$parsed_string2 = '';
$a = explode('</string>', $string2);
foreach ($a as $s) {
$parsed_elm = strip_tags($s);
for ($i = 1; $i <= 2; $i++) {
if (preg_match('/' . $i . '="([^"]+)"/', $s, $match))
$parsed_elm = str_replace('{' . $i .'}', $match[1], $parsed_elm);
}
$parsed_string2 .= $parsed_elm;
}
echo $parsed_string2;
<?php
$rows = array();
$xml = "
<string 1="Jacob" 2="ice cream">{1} likes to have a lot of {2}.</string>
<string 1="John" 2="cream">{1} likes to have a lot of {2}.</string>
"
$parser = xml_parser_create();
xml_parse_into_struct($parser, trim($xml), $xml_values);
foreach ($xml_values as $row){
$finalRow = $row['values'];
foreach ($row['attributes'] as $att => $attval){
$finalRow = str_replace ($finalRow, "{".$att."}", $attval);
}
$rows[] = $finalRow;
}
?>
Here's a version that doesn't use regex, this seemed more straight forward. I don't know how the xml parser would cope with attributes that start with a number though.

get number from file with regexp?

I've got files named
1234_crob.jpg
1234.jpg
2323_örja.bmp
2323.bmp
etc.
How can I just retrieve numbers e.g. 1234 and 2323?
If the file names all start with numbers there is no need to use regular expressions, try this instead:
foreach (glob('/path/to/dir/{0,1,2,3,4,5,6,7,8,9}*', GLOB_BRACE) as $file)
{
echo $file . ' = ' . intval(basename($file)) . "<br />\n";
}
This updated glob pattern will only match filenames that start with a digit, as you requested.
#ghostdog74: You're right.
foreach (glob('/path/to/dir/{0,1,2,3,4,5,6,7,8,9}*', GLOB_BRACE) as $file)
{
echo $file . ' = ' . filter_var(basename($file), FILTER_SANITIZE_NUMBER_INT) . "<br />\n";
}
First explode on the period, and then explode on the underscore, and then your number is the first element in the returned list.
<?php
$str1 = "1234.jpg";
$str2 = "1234_crob.jpg";
$pieces = explode("_",current(explode(".",$str1)));
echo $pieces[0]; // prints 1234
$pieces = explode("_",current(explode(".",$str2)));
echo $pieces[0]; // prints 1234
?>
Yes, I realize this is not a regular expression, but this is too simple a task to use regular expressions.
EDIT: Modified code to work for your newly edited formatting examples.
EDIT: Modified to fit cleanly in one line of code.
Assuming you only pass in filenames (and not filepaths), the following should retrieve all consecutive numbers 0-9:
function getDigits($fn) {
$arr = array();
preg_match('/[0-9]+/', $fn, $arr);
return $arr;
}
EXAMPLE USAGE
var_dump(getDigits('hey_12345.gif'));
/*
output:
array(1) {
[0]=>
string(5) "12345"
}
*/
var_dump(getDigits('123487_dude.jpg'));
/*
output:
array(1) {
[0]=>
string(6) "123487"
}
*/
try this. If you have numbers like 045_test.jpg, using intval will give you 45 instead of 045
$path="/path/[0-9]*";
foreach (glob($path) as $files ){
$base=basename ($files);
$s = preg_split("/[^0-9]/",$base,2);
echo $s[0]."\n";
}

Categories