Форум программистов, компьютерный форум, киберфорум
PHP: RegExp
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827

Найти цифры в конце строки, которая начинается с введенного в $_POST-массив значения

22.06.2019, 01:37. Показов 1608. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть файл из множества строк. Строки начинаются словами (буквенными выражениями на киррилице и латинице), затем идут три цифры, разделенных вертикальным слэшем. Есть форма поиска, куда вводится буквенное выражение (слово). Не могу написать код, чтобы по нажатию кнопки "поиск" находило введенное слово, а ещё лучше - цифру по счету в конце строки.
Содержание текстового файла file.txt:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
охрана|123|0|0|
текст|1|2|3|
книга|4|5|6|
беспомощность|7|8|9|
жест|1|2|3|
дыхание|1|2|3|
сотрясение|0|0|0|
намерения|1|2|3|
последствия|1|2|3|
утверждение|1|2|3|
book|1|2|3|
text|1|2|3|
guard|1|2|3|
Вот код поиска:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
   if (isset($_POST['search']))
   {
$pravS=file_get_contents('file.txt');
echo '<br>'.$pravS.'<br>';
$pr=trim($_POST['poisk']," \t\n\r\0\x0B");  //  на всякий случай все обрезал по бокам
echo $pr.'<br>';  // проверяет, ввелось ли слово
// ниже закоментированы варианты, которые пробовал (часть из них)
//preg_match_all('/\$pr/u',$pravS,$matchPRAV,PREG_PATTERN_ORDER);
//preg_match_all('/$_POST\[\'poisk\'\]/us',$pravS,$matchPRAV,PREG_PATTERN_ORDER);
//$matchP=array_values($matchPRAV[0]);
//print_r($matchP);  // печатает "Array()"
$poisk=preg_match('/\$pr/u',$pravS);
echo $poisk;   // печатает "0"
    }
HTML5
1
2
3
4
<form method="post">
<input type="text" name="poisk" value="" autofocus>
<input type="submit" name="search" value="Найти">
</form>
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.06.2019, 01:37
Ответы с готовыми решениями:

Файлы: если строка начинается с цифры, то перед ней поставить левую круглую скобку, в конце строки - правую
Если строка начинается с цифры, то перед ней поставить левую круглую скобку, а в конец строки - правую круглую скобку.

Найти номер строки, которая начинается с К положительных чисел подряд
//Дана целочисленная матрица À(N, N). // Найдите номер первой из ее строк, // которые начинаются с К положительных чисел подряд. ...

Строки. Найти самую длинную группу цифр, которая начинается и заканчивается на "1"
строки.Дан текст из группы цифр, разделенных пробелами. Найти самую длинную группу цифр, которая начинается и заканчивается на...

13
Невнимательный
 Аватар для ft4l
2840 / 1267 / 358
Регистрация: 08.02.2013
Сообщений: 7,388
Записей в блоге: 2
22.06.2019, 04:09
Имхо тут логичнее что-то типа split/explode
что-то вроде этого, если правильно "цифру по счёту в конце строки"
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
header('Content-type: text/html; charset=utf-8');
$index = -1;
 
if (isset($_POST['poisk'])) {
    if (preg_match('/^\d++$/', $_POST['poisk']))
        $index = 3;
    elseif (preg_match('/^[A-Z_a-zЁА-яё]++$/u', $_POST['poisk']))
        $index = 0;
}
if ($index >= 0){
    // Only right values of $_POST['poisk']
    if (!$handle = fopen("./file.txt", "r"))
            exit('fopen("./file.txt", "r") failed');
    while (!feof($handle) && ($Arr = explode('|', fgets($handle, 256), -1))){
        //with -1 explode returns without "|\n"
        if ($Arr[$index] != $_POST['poisk']) continue;
        echo '<code>'. implode(' | ', $Arr) . "</code><br/>\n";
    }
    fclose($handle);
}
?>
<hr/>
<form method="post">
<input type="text" name="poisk" value="" autofocus>
<input type="submit" name="search" value="Найти">
</form>
Добавлено через 12 минут
....isset($_POST['poisk']) вместо isset($_POST['search'])
1
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
22.06.2019, 10:38  [ТС]
Цитата Сообщение от ft4l Посмотреть сообщение
Имхо тут логичнее что-то типа split/explode
что-то вроде этого, если правильно "цифру по счёту в конце строки"
Я именно с него и начинал, только получилось ещё хуже. Тут то хоть были варианты, что видит цифры, только никак не мог их соотнести с искомым словом.
Ваш вариант вроде бы работает. Строку (слово плюс цифры ищет). Попробую вытянуть из этого все что мне нужно, ато сходу не понял, как отдельную цифру искать. По результату отпишусь. Если что - буду дальше вопросами мучать )
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
22.06.2019, 10:46
PHP
1
2
3
4
$csv = fopen(__DIR__.'/file.txt', 'r');
while (false !== ($data = fgetcsv($csv, 0, '|'))) {
    var_dump($data, $data[count($data) - 1]);
}
1
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
23.06.2019, 17:59  [ТС]
Цитата Сообщение от ft4l Посмотреть сообщение
что-то вроде этого, если правильно "цифру по счёту в конце строки"
Цитата Сообщение от Jewbacabra Посмотреть сообщение
$csv = fopen(__DIR__.'/file.txt', 'r');
while (false !== ($data = fgetcsv($csv, 0, '|'))) {
var_dump($data, $data[count($data) - 1]);
}
Не могу до конца разобраться с вашими вариантами. Они вроде и рабочие, но что делать с ними дальше не могу придумать.
Но придумал как сделать это с помощью регулярки, как и хотел изначально. Только тоже не знаю что потом с этим делать...
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (isset($_POST['otvetit'])) {
if ($_POST['otvet']==$_POST['Rotv']) {
   $otv=$_POST['otvet'];
   echo '<br>Вы правильно ответили<br>';
   $textotvet=file_get_contents('file.txt');
echo $otv;
if (preg_match("/($otv)(\|[\d]+)(\|[\d]+)(\|[\d]+\|)/uim",$textotvet,$m)) 
    {
     echo '<br>'.$otv.'---есть такое слово<br>';
     echo 'Нашли слово со статистикой   <b>'.$m[0].'</b><br>';  // выводит искомую строку с цифрами
     $mm=$m[0];
$zam=preg_replace('/$mm/','этим текстом заменить',$textotvet);
echo '<br>'.$zam.'';
    } else echo 'nety slova';
}
else echo '<br>не правильно. Правильный ответ:   = <b>'.$_POST['Rotv'].'</b>';}
Понимаю, что шаблон можно представить в виде $1$2$3$4 (по количеству скобок). Но как это сделать и назначить им переменные?
0
Невнимательный
 Аватар для ft4l
2840 / 1267 / 358
Регистрация: 08.02.2013
Сообщений: 7,388
Записей в блоге: 2
23.06.2019, 19:18
Цитата Сообщение от DyadyaGe Посмотреть сообщение
if ($_POST['otvet']==$_POST['Rotv']) {
$otv=$_POST['otvet'];
echo '<br>Вы правильно ответили<br>';
Я-бы написал "правильно подсмотрели $_POST['Rotv'] в коде страницы"
Цитата Сообщение от DyadyaGe Посмотреть сообщение
....
$zam=preg_replace('/$mm/','этим текстом заменить',$textotvet);
т.е. зачем-то нужно получить всё содержимое файла и чем-то заменить в нём найденную строку...
для чего?
Из Вашего описания желаемого результата, как и из фрагментов кода не понятно ничего.
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
23.06.2019, 19:36  [ТС]
Цитата Сообщение от ft4l Посмотреть сообщение
Я-бы написал "правильно подсмотрели $_POST['Rotv'] в коде страницы"
Так оно и есть )) Убиваю одним выстрелом двух зайцев: пишу для себя тест-обучалку английского (в результате учу пхп) и учу английский. Поэтому там проверка ответов. Правда у меня возникла другая проблема с этим скрытым полем. Я её в другой теме озвучил.
Цитата Сообщение от ft4l Посмотреть сообщение
т.е. зачем-то нужно получить всё содержимое файла и чем-то заменить в нём найденную строку...
для чего?
Из Вашего описания желаемого результата, как и из фрагментов кода не понятно ничего.
Фактически все эти поиски нужны для получения строки статистики.

Правильный ответ(слово)|число правильных ответов|число неправильных ответов|общее число попыток|

Есть ещё мысли сделать счетчик правильных ответов подряд, но с этим пока можно подождать.
Поэтому в конце концов найденное слово нужно найти и заменить в нем значение статистики. В примере я пока всю строку меняю, но потом надеюсь по образцу поменять нужные мне значения. Тем более что как я прочитал в шаблоне как-то можно куски шаблона приравнивать переменной. Вот четыре куска шаблона $1$2$3$4 приравнять переменным и менять как значения. А записывать в файл как я понимаю функцией file_put_content.
Ну а честно говоря, с вашим вариантом пока не придумал как такое можно сделать
0
Невнимательный
 Аватар для ft4l
2840 / 1267 / 358
Регистрация: 08.02.2013
Сообщений: 7,388
Записей в блоге: 2
24.06.2019, 00:11
Всё-равно не понятно .) слов как-бы 3 , слово-перевод-угаданное
т.е. слова в файле это второе? а ввод юзера это третье
// если не брать в расчёт того что у одного слова чаще несколько переводов

Насчёт изменения-добавления строки, можно конечно тупо считать весь файл, даже например с file() в массив ,
но по идее при возможной одновременной записи надо его всё-равно открывать и блокировать...
Я-бы наверное что-то вроде такого для себя налепил-бы ,)
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
header('Content-type: text/html; charset=utf-8');
 
$words = array(
    array('book', 'книга'),
    array('text', 'текст'),
    array('guard', 'охрана'),
    array('hello', 'привет'),
    array('world', 'мир')
);
$idx = rand(0, sizeof($words)-1);
$ordr = rand(0,1);
 
?>
слово: <?=$words[$idx][($ordr ^ 1)]?>
<form method="post">
<input type="hidden" name="Rotv" value="<?=$words[$idx][$ordr]?>" >
<input type="text" name="otvet" value="" autofocus accesskey="s">
<input type="submit" name="otvetit" value="Ответить" >
<form><hr/>
 
<?php
 
if (isset($_POST['otvetit'])) {
 
    $Rotv = (isset($_POST['Rotv'])/* && другие проверки преобразования*/)? $_POST['Rotv']: '';
    $otvet = (isset($_POST['otvet'])/* && другие проверки преобразования*/)? $_POST['otvet']: '';
    if (trim($otvet) == '') exit('Пустой ответ не засчитывается');
/* Не совсем удобный массив $words
/* поиск по нему наверное как-то так...
 
    function check($ar) {
        global $Rotv;
        return in_array($Rotv, $ar);
    }
    if(!array_filter($words, "check")) exit('Подсунули левое слово ?');
*/
    $otvet = ($Rotv == mb_convert_case($otvet, MB_CASE_LOWER, 'UTF-8'))? TRUE: FALSE;
    // $otvet больше не строка
    print "слово $Rotv:<b>". ($otvet?'Верно':'Неверно') .'</b>';
 
    $fp = fopen('./file.txt', 'r+');
    if (!flock($fp, LOCK_EX)) exit('Не удалось получить блокировку !');
    while (!feof($fp) && !preg_match("/^$Rotv\\|/u", ($line = fgets($fp, 384))));
    if (!feof($fp)) { //        не достигнут конец файла
        $pos = ftell($fp)- strlen($line); //    положение перед совпадением
        $buffer = fread($fp, filesize('./file.txt')); // оставшаяся часть файла
        fseek($fp, $pos, SEEK_SET);
        $line = explode('|',$line);// $line больше не строка
        if ($otvet) ++$line[1];// right
        else ++$line[2];    // wrong
        ++$line[3];         // all
    }
    else{
        // добавление новой строки
        $line = array($Rotv, ($otvet?1:0),($otvet?0:1),1,"\n");
        $buffer = '';
    }
    fputs($fp, implode('|', $line));
    if ($buffer) fputs($fp, $buffer);
    flock($fp, LOCK_UN);
    fclose($fp);
}
Но потом подумал-бы как избавиться всё-таки от записи большого объёма в $buffer,
И $words это тоже жёстко .) Для такого создают базы данных

Добавлено через 27 минут
Цитата Сообщение от ft4l Посмотреть сообщение
if (!feof($fp)) { // не достигнут конец файла
Здесь баг , при нахождении совпадения в последней строке будет считать совпадение не найденным...
Как вариант добавить в цикл && что-то или что-то в preg_match ??....
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
24.06.2019, 01:29  [ТС]
Цитата Сообщение от ft4l Посмотреть сообщение
Всё-равно не понятно .) слов как-бы 3 , слово-перевод-угаданное
т.е. слова в файле это второе? а ввод юзера это третье
Все проще )
Есть файл с парами слов в виде english word=английское слово (значение=перевод). Есть файл ответов, где только перевод и статистика по нем (как раз тот, где данный кусок кода ищет слово с цифрами). Ведь зачем искать пару?
Теоретически можно после статистики втиснуть синонимы через вертикальный слэш, но пока бы разобраться с основной частью. Про БД мне ещё рано думать )) Только с апреля учу пхп.
Дальше тоже все вроде бы просто. Из файла пар слов (словаря) рандомно выбирается английская часть и высвечивается на экране. Её русское значение записывается в скрытое поле (но пока открытое). В соседнем поле вводится русский перевод. По нажатии кнопки введенный текст проверяется на совпадение с текстом из скрытого и проверяется в файле ответов (мини БД). Если там этого ответа раньше не было, то слово со статистикой дописывается и выводится на экран. Если было то просто выводится инфа с числом правильных/неправильных/общего числа переводов (потом все это организуется в отдельной форме в виде какого-нибудь табло).
Выбор пары слов и разбивка на англ и рус часть делается с помощью регулярки и записывается в массив, где англ слова - ключи, а рус - значение.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
header('Content-type: text/html; charset=utf-8');
$vopros=file_get_contents("slovar.txt");
preg_match_all('/(^[\w\s-]+)([=])([\w\s]+$)/mui',$vopros,$match,PREG_PATTERN_ORDER);
$matchS=array_values($match[0]);
//ниже выводится список какого-то числа изучаемых слов по желанию, если их не много, то сразу count
for ($i=0; $i<count($matchS); $i++)
{
  if(($i % 2) == 1)  //odd
{echo '<b style="background-color: yellow; ">'.$matchS[$i].'</b><br>';}
  else echo '<b style="background-color: #aba; ">'.$matchS[$i].'</b><br>';
   }
// закончился необязательный кусок, дальше вывод англ слова на экран, сравнение и все такое
$matchA=array_values($match[1]);
$matchO=array_values($match[3]);
$VO=array_combine($matchA,$matchO);
$randomVO=array_rand($VO);
echo '<br><b>'.$randomVO.'</b>';
 
if (isset($_POST['otvetit'])) 
   { 
    if ($_POST['otvet']==$_POST['Rotv']) 
       {
       $otv=$_POST['otvet'];
       echo '<br>Вы правильно ответили<br>';
       $textotvet=file_get_contents('file.txt');
       echo $otv;
             if (preg_match("/($otv)(\|[\d]+)(\|[\d]+)(\|[\d]+\|)/uim",$textotvet,$m)) 
                 {
                  echo '<br>Nashli   <b>'.$m[0].'</b><br>';
                 $mm=$m[0];
//$zam=preg_replace('/$mm/','кусок для замены',$textotvet);  // эта часть у меня не получается, после неё, как я понимаю, нужно функцию file_put_contents
                  } else echo 'nety slova';
        }
        else echo '<br>не правильно. Правильный ответ:   = <b>'.$_POST['Rotv'].'</b>';  }
?>
 
<form method="post">
<input type="text" name="otvet" value="" autofocus accesskey="s">
<input type="text"  name="Rotv" value="<?=$VO[$randomVO]?>" >
<input type="submit" name="otvetit" value="Ответить" >
</form>
0
Невнимательный
 Аватар для ft4l
2840 / 1267 / 358
Регистрация: 08.02.2013
Сообщений: 7,388
Записей в блоге: 2
24.06.2019, 04:41
Как-бы почти то-же,) но незнаю
, если есть такое большое желание загрузить в память целых два файла сразу...
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php
header('Content-type: text/html; charset=utf-8');
 
//$vopros=file_get_contents("slovar.txt");
//preg_match_all('/(^[\w\s-]+)([=])([\w\s]+$)/mui',$vopros,$match,PREG_PATTERN_ORDER);
#   PREG_PATTERN_ORDER можно не 
//$matchS=array_values($match[0]);
 
$VO = file('slovar.txt', FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
 
//ниже выводится список какого-то числа изучаемых слов по желанию, если их не много, то сразу count
for ($i=0; $i<count($VO); $i++)
{
  if(($i % 2) == 1)  //odd
{echo '<b style="background-color: yellow; ">'.$VO[$i].'</b><br>';}
  else echo '<b style="background-color: #aba; ">'.$VO[$i].'</b><br>';
   }
//$matchA=array_values($match[1]);
//$matchO=array_values($match[3]);
//$VO=array_combine($matchA,$matchO);
array_walk($VO , create_function('&$a', '$a=explode("=",$a);'));
#########  другая структура массива 
#echo '<xmp>';
#print_r($matchS);
 
 
if (isset($_POST['otvetit'])) // здесь нужны разные проверки
{ 
    $otv=$_POST['otvet'];
    $re = '/^('.$_POST['Rotv'].')\|(\d++)\|(\d+)\|(\d+)\|$/uime'; //e == eval
    $count=0;// кол-во замененых совпадения [0 - 1]
 
    $textotvet=file_get_contents('file.txt');
 
    if ($_POST['otvet']==$_POST['Rotv']) 
    {
        echo '<br>Вы правильно ответили<br>';
        echo $otv;
        $textotvet = preg_replace ( $re
            , '"$1|".($2+1)."|". $3 ."|".($4+1)."|"'
            , $textotvet, 1 ,$count);
        if ($count == 0){ // небыло найдено
            $textotvet .= $_POST['Rotv'] .'|'. 1 .'|'. 0 .'|'. 1 ."|\n";
        }
    } else {
        echo '<br>Вы не правильно ответили<br>';
        $textotvet = preg_replace ( $re
            , '"$1|". $2 ."|".($3+1)."|".($4+1)."|"'
            , $textotvet, 1 ,$count);
        if ($count == 0){ // небыло найдено
            $textotvet .= $_POST['Rotv'] .'|'. 0 .'|'. 1 .'|'. 1 ."|\n";
        }
    }
    
    file_put_contents('file.txt', $textotvet);
}
 
$random=rand(0,count($VO)-1);
$key = rand(0,1);// 
echo '<br><b>'.$VO[$random][$key].'</b>';
?>
 
<form method="post">
<input type="text" name="otvet" value="" autofocus accesskey="s">
<input type="text"  name="Rotv" value="<?=$VO[$random][($key ^1)]?>" >
<input type="submit" name="otvetit" value="Ответить" >
</form>
Тут как-бы, кроме расхода памяти, сильно может стать заметным падение быстродействия...
Особенно если в файлах 10-ки тысяч пар слов .) и не из-за того, что Regex работают медленнее строковых и т.п.

Добавлено через 32 минуты
И да, модификатор /i не будет правильно работать с utf-8, если в системе нет локали типа ru_RU.UTF-8
тогда в начале нужно поставить setlocale(LC_ALL, 'ru_RU.UTF-8');
, как и например strtoupper() strtolower() ...
В виндовс я не знаю какая нужна строка и есть-ли такая
1
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
24.06.2019, 11:59
Все делается гораздо проще с использованием бд, хотябы sqlite. Если бд совсем нет желания использовать, то так:
PHP
1
2
3
4
5
// запись данных в файл
$file = __DIR__.'/storage.php';
$data = ['foo' => 'bar'];
$content = '<'.'?php return '.var_export($dat, true).';';
file_put_contents($file, $content, LOCK_EX);
PHP
1
2
3
4
5
6
7
8
// чтение данных
$file = __DIR__.'/storage.php';
$data = @include $file;
if ($data === false) {
    var_dump(error_get_last());
    return;
}
var_dump($data);
1
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
24.06.2019, 21:54  [ТС]
Цитата Сообщение от ft4l Посмотреть сообщение
Как-бы почти то-же,) но незнаю
, если есть такое большое желание загрузить в память целых два файла сразу...
Ну не знаю, почему-то кажется что так проще, не путать мухи с котлетами. Тем более есть мысли файл с парами слов регулярно обновлять, то увеличивать, то уменьшать, то подсоединять пару. Ведь слова учатся. Конечно повторение - мать учения, но зачем по сто раз одно и тоже слово? тем более что учить лучше небольшими объемами, слов по 20-30, ну до 50 в списке. А те которые уже прям совсем хорошо знаешь, раз по 20 подряд правильно ответил, хотелось бы каким-то образом удалять из списка и на их место новую пару записать. Через время, конечно к ним тоже надо будет возвращаться, но потому и есть желание подключать аж два файла с парами. А файл с ответами будет всю статистику хранить. Хотя её можно по идее обнулять. Но это в будущем. Потому и хочу чуток позже подумать над счетчиком правильных ответов подряд. И если сам не придумаю, буду звать на помощь )))
Цитата Сообщение от ft4l Посмотреть сообщение
Тут как-бы, кроме расхода памяти, сильно может стать заметным падение быстродействия...
Особенно если в файлах 10-ки тысяч пар слов
Потому и хочется пару файлов с парами слов. Одна, так сказать для активного обучения, вторая - для вспомнить иногда, а может и третий-четвертый... (допустим по темам)
Ещё ваш пример работает, но есть пару но:
1. Дает слова и англ и рус. А хотелось только англ, а уже к ним перевод писать в поле инпут.
2. Пишется затирая все ответы со статистикой, оставляет только последний.
3. У меня ругался на eval, типа нет такого модификатора, но при этом все меняло. Ошибка такая
PHP
1
Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead
Поэтому я переделал, глядя на ваш пример. И будете смеяться, но свой вариант хотел ещё несколько часов назад выложить. НО вдруг перестал работать шаблон. Вернее я потом понял, что это именно шаблон виноват. А именно - перестал срабатывать знак $. Почему - до сих пор не пойму. Хотя сто проц работал с ним. Ощущение, что как-то поменялся формат файла статистики ответов. Я его несколько раз чистил, чтоб быстрее проверить запись и реакцию на отсутствие слова в нем.
Вот, что получилось:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
header('Content-type: text/html; charset=utf-8');
$vopros=file_get_contents("angl.txt");
 
preg_match_all('/(^[\w\s-]+)([=])([\w\s]+$)/mui',$vopros,$match,PREG_PATTERN_ORDER);
$matchS=array_values($match[0]);
for ($i=0; $i<count($matchS); $i++)
{
  if(($i % 2) == 1)  //odd
{echo '<b style="background-color: yellow; ">'.$matchS[$i].'</b><br>';}
  else echo '<b style="background-color: #aba; ">'.$matchS[$i].'</b><br>';
   }
 
$matchA=array_values($match[1]);
$matchO=array_values($match[3]);
 
$randomVO=array_rand($VO);
echo '<br><b>'.$randomVO.'</b>';
 
if (isset($_POST['otvetit'])) 
       {  
    $otv=$_POST['otvet'];
    $re = '/^('.$_POST['Rotv'].')\|(\d++)\|(\d+)\|(\d+)\|$/uim'; 
    $count=0;// кол-во замененых совпадения [0 - 1]  // так и не понял, где оно применяется
 
    $textotvet=file_get_contents('file-otvet.txt');
 if (  $_POST['otvet']==$_POST['Rotv']) 
      {
       $otv=$_POST['otvet'];
        echo '<br>Вы правильно ответили     <b>ответ    :'.$otv.'</b><br>';
      if (preg_match("/^($otv)\|([\d]+)\|(\d+)\|(\d+)\|/uim",$textotvet,$m))
         {
          echo '<br>Нашли  статистику по слову    <b>'.$m[0].'</b><br>';
          echo 'правильных ответов было         '.$m[2].'<br>';
          echo 'не правильных ответов было        '.$m[3].'<br>';
          echo 'всего ответов было               '.$m[4].'<br>';
                  $m1=$m[2]+1; echo 'стало правильных     '.$m1.'<br>'; 
                  $m3=$m[4]+1;echo 'стало всего   '.$m3.'<br>'; 
                  $zap = preg_replace ( "/^($otv)\|(\d++)\|(\d+)\|(\d+)\|/uim"
                  ,"$1|$m1|$3 |$m3|" 
                  , $textotvet, 1 ,$count);
                   file_put_contents('file-otv.txt',$zap);                   
                 }
        elseif
              //(!strpos(file_get_contents('file-otvet.txt'),$_POST['otvet']))  // работает так тоже, пока не решил как лучше
             (!preg_match("/^($otv)\|([\d]+)\|(\d+)\|(\d+)\|/uim",$textotvet,$m))
                  {
                   $textotvet1='file-otvet.txt';
                    echo '<br>отсутствовало в ответах, поэтому дописали в файл ответов со статистикой<br>';
                    $zap=$_POST['otvet'].'|1|0|1|';
                    file_put_contents($textotvet1, PHP_EOL.$zap, FILE_APPEND);
                    }
        }
  elseif ($_POST['Rotv']!==$_POST['otvet'])
        {
         $randotv=$_POST['Rotv'];
         echo '<br>не правильно. Правильный ответ:   = <b>'.$randotv.'</b>';    
      if (preg_match("/($randotv)\|(\d++)\|(\d+)\|(\d+)\|/uim",$textotvet,$m))
            {
             echo '<br>Нашли  статистику по слову    <b>'.$m[0].'</b><br>';
             echo 'правильных попыток было         '.$m[2].'<br>';
             echo 'не правильных попыток было        '.$m[3].'<br>';
             echo 'всего попыток было               '.$m[4].'<br>';
                  $m2=$m[3]+1;echo 'стало неправильных    '.$m2.'<br>'; 
                  $m3=$m[4]+1;echo 'стало всего   '.$m3.'<br>'; 
                  $zap = preg_replace ( "/^($randotv)\|(\d++)\|(\d+)\|(\d+)\|/uim"
                  ,"$1|$2|$m2 |$m3|" 
                  , $textotvet, 1 ,$count);
                   file_put_contents('file-otv.txt',$zap);                  
                 }    
            }        
}
//  Ниже обнуление, но пока обнуляет только первое слово
if (isset($_POST['obnul']))
   {
       $textotvet=file_get_contents('file-otv.txt');  
      if  (preg_match("/(^[\w\s]+)\|(\d++)\|(\d+)\|(\d+)\|/uim",$textotvet,$m))
                  $m1=$m[2]*0; echo '<br>стало правильных попыток    '.$m1.'<br>'; 
                  $m2=$m[3]*0;echo 'стало неправильных попыток    '.$m2.'<br>'; 
                  $m3=$m[4]*0;echo 'стало всего попыток   '.$m3.'<br>'; 
 
                  $textotvet = preg_replace("/(^[\w\s]+)\|(\d++)\|(\d+)\|(\d+)\|/uim"
                  ,"<b>$1|$m1|$m2 |$m3|</b>" 
                  , $textotvet, 1 ,$count);
           }    
   }
?>
 
 
<form method="post">
<input type="text" name="otvet" value="" autofocus accesskey="s">
<div class="hidden">
<input type="text"  name="Rotv" value="<?=$VO[$randomVO]?>" >
</div>
<input type="submit" name="otvetit" value="Ответить" >
</form>
<form method="post">
<input type="submit" name="obnul" value="Обнулить всё">
</form>
Цитата Сообщение от ft4l Посмотреть сообщение
И да, модификатор /i не будет правильно работать с utf-8, если в системе нет локали типа ru_RU.UTF-8
тогда в начале нужно поставить setlocale(LC_ALL, 'ru_RU.UTF-8');
Спс, учту на будущее.
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Все делается гораздо проще с использованием бд, хотябы sqlite. Если бд совсем нет желания использовать, то так:
БД просто не знаю. Использую то, что хоть немного знаю. Но обязательно позже будет с БД )
И почему-то в этот раз с вашим примером сходу не разобрался... Особенно с файлом "storage.php".

Добавлено через 29 минут
Нашел у себя небольшую опечатку. Везде в шаблоне замены стоит лишний пробел в третей части шаблона
PHP
1
2
3
                  $zap = preg_replace ( "/^($otv)\|(\d++)\|(\d+)\|(\d+)\|/uim"
                  ,"$1|$m1|$3 |$m3|" 
                  , $textotvet, 1 ,$count);
В результате, после перезаписи, слов не "узнавалось" и записывалось в конец файла
Надо так:
PHP
1
2
3
                  $zap = preg_replace ( "/^($otv)\|(\d++)\|(\d+)\|(\d+)\|/uim"
                  ,"$1|$m1|$3|$m3|" 
                  , $textotvet, 1 ,$count);
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
03.07.2019, 18:09  [ТС]
Дошли руки опять вернуться к этой задаче.
Цитата Сообщение от Jewbacabra Посмотреть сообщение
// запись данных в файл
Таким образом остаются кавычки в начале и конце файла, поэтому я просто применил "implode" и все получилось
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (isset($_POST['obnul']))
   {
       $textotvet=file_get_contents('file-otvet.txt');  
 
      if  (preg_match_all("/(^[\w\s\-]+)\|(\d++)\|(\d+)\|(\d+)\|/uim",$textotvet,$mv,PREG_PATTERN_ORDER))
         {
          $MMVV=array_values($mv[1]);
          foreach ($MMVV as $key=>$val)
              {
              $val=$val.'|0|0|0|';
              $valm[]=$val;
              }
$vali=implode(''.PHP_EOL.'',$valm);
$file='file-otvet.txt';
file_put_contents($file, $vali, LOCK_EX);
          }
   }
Цитата Сообщение от Jewbacabra Посмотреть сообщение
while (false !== ($data = fgetcsv($csv, 0, '|')))
Вернулся к этому варианту, почти разобрался. Только в таком виде у меня не находит совпадение с первым значением массива.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$csv = fopen('file-otvet.txt', 'r');
while (false !== ($data = fgetcsv($csv,0, '|'))) {
  $text[]=$data[0];
  $stat1[]=$data[1];
  $stat2[]=$data[2];
  $stat3[]=$data[3];
  $count=count($data);  // чисто для проверки количества элементов
 }
for ($i=0; $i<count($text); $i++)
  {
  echo $text[$i].'|'.$stat1[$i].'|'.$stat2[$i].'|'.$stat3[$i].'|<br>';
  }
// Проверка и  Действия в случае правильного ответа
if (isset($_POST['search_otvet'])) 
   {  
      $keyotv=array_search(''.$_POST['otvet'].'',$rus);
      if ($keyotv) 
         {
          echo $keyotv.'<br>'; // позиция совпадения
          echo $text[$keyotv].'|'.$stat1[$keyotv].'|'.$stat2[$keyotv].'|'.$stat3[$keyotv].'|<br>';
          }
       else echo '<br>Не нашли совпадений<br>';
  }
И если файл ответов в таком виде:
охрана|3|4|5|
беспомощность|4|5|6|
обязанность|5|6|7|
дыхание|6|7|8|
То слово "охрана" не найдет. Даже, если я отдельно ответы сразу в массив записываю, а не из файла беру.
Цитата Сообщение от ft4l Посмотреть сообщение
если не брать в расчёт того что у одного слова чаще несколько переводов
Попробовал с синонимами в переводе, но поскольку не придумал как быть с произвольным числом синонимов, пока выскакивает НОТИС с предупреждением, что такого ключа нет, если в каком-т слове синонимов больше, чем у остальных.
PHP
1
2
3
4
5
6
7
8
9
10
  $text[]=$data[0];
  $stat1[]=$data[1];
  $stat2[]=$data[2];
  $stat3[]=$data[3];
  $stat4[]=$data[4];
// $stat5[]=$data[5];
// $stat6[]=$data[6];
  $stat7[]=$data[7];
  $count=count($data);
Notice: Undefined offset: 7  // и так по числу массивов без этого значения
А $count принимает значение наименьшего числа элементов. Хотя при этом распечатывает массив
PHP
1
2
print_r($stat7);echo '<br>';
Array ( [0] => [1] => тычки [2] => [3] => [4] => критика [5] => [6] => [7] => [8] => )
Добавлено через 2 часа 28 минут
Цитата Сообщение от DyadyaGe Посмотреть сообщение
То слово "охрана" не найдет. Даже, если я отдельно ответы сразу в массив записываю, а не из файла беру
Проверил ещё и функцию strpos. Она тоже не находит первое слово (перед этим все слова соединил в строку функцией implode).
0
18 / 13 / 6
Регистрация: 04.04.2019
Сообщений: 827
04.07.2019, 01:10  [ТС]
Разобрался с поиском первого слова. Оказывается strpos возвращает позицию или false, поэтому условие === true никогда не выполнится, эта функция true не возвращает. То же самое и с array_search. Поэтому заменил на:
PHP
1
        if ($keyotv!==false)
И все стало искать. Видимо вопрос решен.
Ну а по поводу поиска синонимов, если не придумаю как быть с разноразмерными массивами, то начну новую тему. Если придумаю - напишу тут.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.07.2019, 01:10
Помогаю со студенческими работами здесь

Строки. Найти самую длинную группу цифр, которая начинается и заканчивается на "1" и поменять ее местами с первой группой
Строки. Найти самую длинную группу цифр, которая начинается и заканчивается на &quot;1&quot; и поменять ее местами с первой группой ...

Удаление цифры 0, в конце строки TASM
Задание:написать программу, которая возвращает строку, в конце которой удалены все цифры 0 и символы с кодом меньше пробела. помогите...

массив - добавление цифры в конце урла
Необходимо вывести на экран 10 ссылок - в каждой ссылке добавлять по цифре www.test.ru/index1.php www.test.ru/index2.php ...

Программа, которая выводит на экран все цифры введенного пользователем числа через пробел в прямом порядке
Нужна программа, которая выводит на экран все цифры введенного пользователем числа через пробел в прямом порядке. Я уже делал, чтоб...

У каждой строки из введенного набора все цифры заменить на пробелы
Разработать функцию Change(const S:string):string, возвращающую строку, в которой все цифры строки S заменены на пробелы. С помощью данной...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru