I need to compare two language files - English and German. Each text file has one word/phrase per line. Word/phrase [x] in first language is word/phrase [x] in second language. The translated word is on the same line in the second file.
I tried to get the translation using the following code, but it seems that the loop does not work. I always get "none". Any ideas?
function translation($word,$service,$sprache1,$sprache2){
$typus ="transl";
$mypath = "data/".$service."/";
mkdir($mypath,0777,TRUE);
//fh - First language file
$myFile = $mypath."".$typus."-".$sprache1.".txt";
$fh = file($myFile) or die("can't open file");
//fh2 - Second language file
$myFile2 = $mypath."".$typus."-".$sprache2.".txt";
$fh2 = file($myFile2) or die("can't open file");
$x=0;
$result = "none";
foreach ($fh as $line) {
if (stripos($word,$line))
{$result = $fh2[$x];
break;
}
$x=$x+1;
}
return $result;
}
I think your problem is in wrong if statement.
The point is that stripos (like strpos) can return 0 or false as a result.
For example if you search for 'cat' in a word 'cats' stripos will return 0, as it's the first position of cat-string.
On the other side, if you search 'dog' in a word 'cats' stripos will return false as nothing is found.
So in you function the if case should be more strict:
if (stripos($word,$line) !== false)
This means that your word is found even if it starts from position 0.
You current if statement doesn't allow 0 (zero) value to be accepted.
After testing your code I found 2 different problems.
First of all, be careful with stripos. This function returns 0 if the $needle is found at the beginning (i.e. position 0), and false if the $needle was not found. In PHP, 0 is eval'd to false by default.
You should change your if statement to:
if(stripos($word, $line) !== false)
Note the !== operator, which is stronger than !=.
The second and most important problem, which prevents your function from working, is that you compare lines which can contains invisible characters (e.g. "newline" chars). You should trim the strings before comparing them.
I'd change your if statement for:
if(trim($word) === trim($line))
which is simpler. Or if you really want to keep stripos:
if(stripos(trim($word), trim($line)) !== false)
Related
I have a PHP script that loops through each row of a CSV file and organizes each line into an array:
$counter = 0;
$file = file($ReturnFile);
foreach($file as $k){
if(preg_match('/"/', $k)==1){
$csv[] = explode(',', $k);
$counter++;
}
}
...
while($x<$counter){
$line=$csv[$x];
This works; my question is about how to find a substring within each line. This:
foreach($line as $value){
if($value==$name_search){
// action
works if the value of $line is exactly equal to the value of $name_search ($name_search is a person's last name). However, this doesn't work if there is a space or additional characters in the value of $line (for example: $line equal to "Wilson (ID: 345)" or "Wilson " won't match a $name_search value of "Wilson".
So far I've tried:
if(strpos($value, $res_name_search) !== false){
if(substr($value, 0, strrpos($value, ' '))==$res_name_search){
if(substr(strval($value), 0, strrpos(strval($value), ' '))==$res_name_search){
without success ... Do I have a syntax error and/or is there a better way to accomplish this?
I think you have inverted the parameters. The following should work:
if (strpos($res_name_search, $value) !== false)
A minor note: use stripos for case-insensitive search.
Try to use strpos like this: if (strpos($res_name_search, $value))
use php TRIM function
Convert to either of the lowercase or uppercase before compairing
use var_dump to check the data type
instead of using var_dump type cast $value and $name_search to STRING
also check ===
Remove spaces (if required)
Use regular expression to remove (, ), :, -, ; etc...
and of course apply function strpos
You can apply above mentioned points in your logic (Order of points may be different)
Try this:
$str = 'This is my test: wilson ';
$search = "wilson";
if(strpos(strtolower($str), strtolower($search)) !== false){
echo 'found it';
}
You can also try this:
if (preg_match('/'.strtolower($res_name_search).'/', strtolower($value)))
This is the sort of situations for which the built-in PHP function stristr exists. This function is the case-insensitive equivalent of the strstr function which, according to the docs:
Returns part of haystack string starting from and including the first occurrence of needle to the end of haystack.
Using this function, achieving such a task becomes as easy as:
foreach($line as $value){
if( stristr($value, $name_search) !== FALSE){
// substring was found in search string, perform your action
You can read more about it in the official documentation
I hope this helps.
I advice you to use fgetcsv function, this will return you an array of your columns for each iteration as follow :
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// ...
}
If in your CSV file, the column NAME is in position 2 for example and you want to know if token exist, just use
if (strpos('Wilson', $data[2] !== FALSE) {
// do your job
}
if you want to deal with case-insentivie, use stripos function
This should be a simple task, but searching for it all day I still can't figure out what I'm missing
I'm trying to open a file using PHP's glob() that begins with a specific number
Example filenames in a directory:
1.txt
123.txt
10 some text.txt
100 Some Other Text.txt
The filenames always begin with a unique number (which is what i need to use to find the right file) and are optionally followed by a space and some text and finally the .txt extension
My problem is that no matter what I do, if i try to match the number 1 in the example folder above it will match every file that begins with 1, but I need to open only the file that starts with exactly 1, no matter what follows it, whether it be a space and text or just .txt
Some example regex that does not succeed at the task:
filepath/($number)*.txt
filepath/([($number)])( |*.?)*.txt
filepath/($number)( |*.?)*.txt
I'm sure there's a very simple solution to this... If possible I'd like to avoid loading every single file into a PHP array and using PHP to check every item for the one that begins with only the exact number, when surely regex can do it in a single action
A bonus would be if you also know how to turn the optional text between the number and the extension into a variable, but that is entirely optional as it's my next task after I figure this one out
The Regex you want to use is: ^99(\D+\.txt)$
$re = "/^99(\D+\.txt)$/";
preg_match($re, $str, $matches);
This will match:
99.txt
99files.txt
but not:
199.txt
999.txt
99
99.txt.xml
99filesoftxt.dat
The ( ) around the \D+.txt will create a capturing group which will contain your file name.
I believe this is what you want OP:
$regex = '/' . $number . '[^0-9][\S\s]+/';
This matches the number, then any character that isn't a number, then any other characters. If the number is 1, this would match:
1.txt
1abc.txt
1 abc.txt
1_abc.txt
1qrx.txt
But it would not match:
1
12.txt
2.txt
11.txt
1.
Here you go:
<?php
function findFileWithNumericPrefix($filepath, $prefix)
{
if (($dir = opendir($filepath)) === false) {
return false;
}
while (($filename = readdir($dir)) !== false) {
if (preg_match("/^$prefix\D/", $filename) === 1) {
closedir($dir);
return $filename;
}
}
closedir($dir);
return false;
}
$file = findFileWithNumericPrefix('/base/file/path', 1);
if ($file !== false) {
echo "Found file: $file";
}
?>
With your example directory listing, the result is:
Found file: 1.txt
You can use a regex like this:
^10\D.*txt$
^--- use the number you want
Working demo
For intance:
$re = "/^10\\D.*txt$/m";
$str = "1.txt\n123.txt\n10 some text2.txt\n100 Some Other2 Text.txt";
preg_match_all($re, $str, $matches);
// will match only 10 some text.txt
I have the following code/string:
$ids="#222#,#333#,#555#";
When I'm searching for a part using:
if(strpos($ids,"#222#"))
it won't find it. But when I'm searching without the hashes, it works using:
if(strpos($ids,"222"))
I've already tried using strval for the search parameter, but this won't work also.
strpos starts counting from 0, and returns false if nothing is found. You need to check if it's false with === like this...
if (strpos($ids, '#222#') === false) // not found
Or use !== if you want the opposite test...
if (strpos($ids, '#222#') !== false) // found
See the PHP Manual entry for more information
You are not explecitely testing for FALSE when using strpos. Use it like this:
if(strpos($string, '#222#') !== FALSE) {
// found
} else {
// not found
}
Explanation: You are using it like this:
if(strpos($string, '#222#')) {
// found
}
What is the problem with this? Answer: strpos() will return the position in string where the substring was found. In you case 0 as its at the beginning of the string. But 0 will be treated as false by PHP unless you issue an explicit check with === or !==.
It is working as expected. strpos() returns 0 because the string you're searching for is at the beginning of the word. You need to do an equality search:
Update your if() statement as follows:
if(strpos($ids, '#222') !== false)
{
// string was found!
}
Try with this :
$ids="#222#,#333#,#555#";
if(strpos($ids,"#222#") !== false)
{
echo "found";
}
You should use !== because the position of '#222#' is the 0th (first) character.
So I know how to open a file in php is done using
fopen("file.txt", 'r') ;
but i want to get one line in the file and so some string manipulation on it.
such as " Serving this with <0101010> "
I want to find the line that starts with "Serving this" and take the whole line add it to $line
Then i will get remove the <> and add it to $number , and same for <0101010>
names of methods that can be used would be just perfect
Okay, the simple method you probably want to use is:
foreach (file("file.txt") as $line) {
if (strpos($line, "Serving this with") === 0) {
print "found";
The file function is easier than fopen/fread, as it returns a list of lines already. And the strpos function simply searches the string and returns the position. It must be checked with === 0 here, because it could also return false.
Instead of printing "found" you want to extract something, so you must again use strpos to find your delimeters < and > and then extract the part with substr:
$l = strpos($line, "<"); // well, actually needs more logic,
$r = strpos($line, ">"); // some if tests, if both are true
$wanthave = substr($line, $l, $r - $l + 1);
A simpler option I would use are regular expressions. And the regex itself looks simple enough in your case:
preg_match_all('/^Serving this with <(\d+)>/m',
file_get_contens("file.txt"),
$matches);
print_r($matches[1]);
you can also use fgets() read file line by line.
$line = fgets($file_handle);
Question 1: How can I manually move the fgetc file pointer from its current location to the next line?
I'm reading in data character by character until a specified number of delimiters are counted. Once the delimiter count reaches a certain number, it needs to copy the remainder of the line until a new line (the record delimiter). Then I need to start copying character by character again starting at the next record.
Question 2: Is manually moving the file pointer to the next line the right idea? I would just explode(at "\n") but I have to count the pipe delimiters first because "\n" isn't always the record delimiter.
Here's my code (it puts all the data into the correct record until it reaches the last delimiter '|' in the record. It then puts the rest of the line into the next record because I haven't figured out how to make it correctly look for the '\n' after specified # of | are counted):
$file=fopen("source_data.txt","r") or exit ("File Open Error");
$record_incrementor = 0;
$pipe_counter = 0;
while (!feof($file))
{
$char_buffer = fgetc($file);
$str_buffer[] = $char_buffer;
if($char_buffer == '|')
{
$pipe_counter++;
}
if($pipe_counter == 46) //Maybe Change to 46
{
$database[$record_incrementor] = $str_buffer;
$record_incrementor++;
$str_buffer = NULL;
$pipe_counter = 0;
}
}
Sample Data:
1378|2009-12-13 11:51:45.783000000|"Pro" |"B13F28"||""|1||""|""|""|||False|||""|""|""|""||""||||||2010-12-15 11:51:51.330000000|108||||||""||||||False|""|""|False|""|||False
1379|2009-12-13 12:23:23.327000000|"TLUG"|"TUG"||""|1||""|""|""|||False|||""|""|""|""||""||||||1943-04-19 00:00:00|||||||""||||||False|""|""|False|""|||False
I'd say that doing this via file handling functions is a bit clumsy, when it could be done via regular expression quite easily. Just read the entire file into a string using file_get_contents() and doing a regular expression like /^(([^|]*\|){47}([^\r\n]*))/m with preg_match_all() could find you all the rows (which you can then explode() using | as the delimiter and setting 48 as the limit for number of fields.
Here is a working example function. The function takes the file name, field delimiter and the number of fields per row as the arguments. The function returns 2 dimensional array where first index is the data row number and the second is the field number.
function loadPipeData ($file, $delim = '|', $fieldCount = 48)
{
$contents = file_get_contents($file);
$d = preg_quote($delim, '/');
preg_match_all("/^(([^$d]*$d){" . ($fieldCount - 1) . '}([^\r\n]*))/m', $contents, $match);
$return = array();
foreach ($match[0] as $line)
{
$return[] = explode($delim, $line, $fieldCount);
}
return $return;
}
var_dump(loadPipeData('source_data.txt'));
(Note: this is a solution to the original problem)
You can read to the end of the line like this:
while (!feof($file) && fgetc($file) !== '\n');
As for whether or not fgetc is the right way to do this... your format makes it difficult to use anything else. You can't split on \n, because there may be newlines within a field, and you can't split on |, because the end of the record doesn't have a pipe.
The only other option I can think is to use preg_match_all:
$buffer = file_get_contents('test.txt');
preg_match_all('/((?:[^|]*\|){45}[^\n]*\n)/', $buffer, $matches);
foreach ($matches[0] as $row) {
$fields = explode('|', $row);
}
Answer to the modified question:
To read from the file pointer to the end of the line, you can simply use the file reading function fgets(). It returns everything from the current file pointer position until it reaches the end of the line (and also returns the end of the line character(s)). After the function call, the file reading pointer has been moved to the beginning of the next line.