За последние 24 часа нас посетили 34359 программистов и 1819 роботов. Сейчас ищут 847 программистов ...

Найти слово и изменить число, находящееся рядом

Тема в разделе "PHP для новичков", создана пользователем Fox-, 7 фев 2018.

  1. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    Здравствуйте, пишу код который ищет слово(ник) в txt файле и меняет его число.

    Ник найти не сложно, но нужно отступить от ника три знака ||| и добраться до цифр

    содержимое 1.txt (строк много, файл может достигать более 10 мб)
    Код (Text):
    1.  
    2. User|Moskva|mail|20
    3. Vlad|Moskva|mail|20
    4. Vadim|Moskva|mail|54
    и тд
    вывести число могу, но нужно его изменить, то есть прибавлять 20.
    Кратко:
    -Найти ник(у него 10 например), к его сумме прибавить 20, и удалить старое число т.е 10 и записать вместо него новую сумму 30

    Вот код, помог AlexandrS:
    PHP:
    1. $var = "User";
    2. $arrayDump = file("./1.txt", FILE_IGNORE_NEW_LINES);
    3. foreach ($arrayDump as $strDump) {
    4.  
    5.     list($name, $sit, $mail, $nm) = explode("|", $strDump);
    6.     if (trim($name) == trim($var)) {
    7. echo "$nm";
    8.      }    
    как после условия на идентичность ника, перепрыгнуть через 3 знака ||| и сложить так как писал выше? explode не нужен наверное предпологаю, т.к нужно по знакам | ориентироваться
     
    #1 Fox-, 7 фев 2018
    Последнее редактирование: 7 фев 2018
  2. TeslaFeo

    TeslaFeo Старожил

    С нами с:
    9 мар 2016
    Сообщения:
    2.984
    Симпатии:
    759
    а условие на идентичность ника по твоему это:
    ??
    Кликни на trim в своём коде, и почитай, что он делает)
    почитай про list и explode таким же способом.
    --- Добавлено ---
    сорирую, перепутал идентичность с уникальностью)
    --- Добавлено ---
    но это:
    актуально
     
  3. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    @Fox- , вам случаем структура данных в текстовом файле не напоминает CSV? ;) Я бы пригляделся к этому. Может и задачка показалась бы простой...
     
  4. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    бывает.
    Прочел, норм. Знаете как осуществить? Найти ник и прибавить к числу
    --- Добавлено ---
    Она и есть в принципе,вы на работу с str_getcsv намекаете? нужно банально найдя ник, сложить числа и сохранить ответ вместо старого, перерыл гугля, но мало полезного нашел, я сам написал бы, но не красиво получается пока. А некоторые действия попросту не смогу написать
     
    #4 Fox-, 7 фев 2018
    Последнее редактирование: 7 фев 2018
  5. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    структуру данных изменить пришлось, теперь данные так выглядят
    Код (Text):
    1.  
    2. User|<User>50</User>
    3. Vlad|<Vlad>21</Vlad>
    4. Vadim|<Vadim>20</Vadim>
    иначе, если как в первом варианте через | не знаю как. С тегами удобнее работать
    Жду может кто-нибудь знает, как через три ||| все таки перепрыгнуть и число прибавить и тд
    Вопрос открыт )
     
  6. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Давайте так попробуем:
    PHP:
    1. <?php
    2. function replace_number($arr, $name, $num = 20){
    3.     $re = '/(^'.$name.'\|[^|]+\|[^|]+\|)(\d+)$/';
    4.     foreach($arr as &$line) {
    5.         $line = preg_replace_callback($re, function($m) use($num){
    6.             return $m[1] . ($m[2] + $num);
    7.         }, $line);
    8.     }
    9.     return $arr;
    10. }
    11.  
    12. $data = [
    13.     'User|Moskva|mail|20',
    14.     'Vlad|Moskva|mail|20',
    15.     'Vadim|Moskva|mail|54'
    16. ];
    17. print_r(replace_number($data, 'Vlad'));
    18. /*
    19. Array
    20. (
    21.     [0] => User|Moskva|mail|20
    22.     [1] => Vlad|Moskva|mail|40
    23.     [2] => Vadim|Moskva|mail|54
    24. )
    25. */
    26. print_r(replace_number($data, 'Vadim', 100));
    27. /*
    28. Array
    29. (
    30.     [0] => User|Moskva|mail|20
    31.     [1] => Vlad|Moskva|mail|20
    32.     [2] => Vadim|Moskva|mail|154
    33. )
    34. */
     
    Fox- нравится это.
  7. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    @Deonis Все работает, спасибо, но когда данные с txt беру, не работает.
    PHP:
    1. <?php
    2. $name1="User";
    3. //$num1000 = '1000';
    4.  
    5. $txt = file_get_contents('ok.txt');
    6.  
    7. function replace_number($arr, $name, $num = 20){
    8.     $re = '/(^'.$name.'\|[^|]+\|[^|]+\|)(\d+)$/';
    9.     foreach($arr as &$line) {
    10.         $line = preg_replace_callback($re, function($m) use($num){
    11.             return $m[1] . ($m[2] + $num);
    12.         }, $line);
    13.     }
    14.     return $arr;
    15. }
    16.  
    17. print_r(replace_number($txt, $name1, 20));
    18.  
    19.  
    20. ?>
    --- Добавлено ---
    Еще вопрос, в переменной число, как можно в txt файле его между тегом например <User></User> вставить, но перед этим удалив содержимое тега. И Сохранить измененный txt
     
  8. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    В начале в вашем коде вы использовали функцию file(). Что изменилось с того момента?
    Регулярки и теги - понятия плохосовместимые. И у меня создалось впечатление, что вы постоянно пытаетесь усложнить задачу. ))
     
  9. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    Да нет усложнить не пытаюсь) Хотел упростить, сейчас я с таким содержимым txt файла хочу попробовать разобраться:

    Код (Text):
    1. User|<User>50</User>
    2. Vlad|<Vlad>21</Vlad>
    3. Vadim|<Vadim>20</Vadim>
    , ваш код я не могу подкорректировать под себя ) то одна ошибка то вторая т.к. я любитель))
    вот так решил попробовать
    Код (Text):
    1.  
    2. $name="User";
    3. $num20 = '20';
    4.  
    5. $txt = file_get_contents('ok.txt');
    6.  
    7. if(preg_match("~<$name>(.*)</$name>~",$txt,$preg))
    8.   $bln= $preg[1];
    9.   echo $bln;
    10.  
    11.   echo "<br/>\$num20 + \$bln = ". ($num20 + $bln);
    12.   $newbln=($num20 + $bln);  // итог, это число нужно расположить между тегов <User></User>  перед этим удалив содержимое тега.в txt файле ok.txt
     
    #9 Fox-, 8 фев 2018
    Последнее редактирование: 8 фев 2018
  10. TeslaFeo

    TeslaFeo Старожил

    С нами с:
    9 мар 2016
    Сообщения:
    2.984
    Симпатии:
    759
    может ты бы всё таки почитал про explode() и осознал бы наконец, что он разбивает строку на массив по указанному разделителю.
    И тогда бы ты понял, что прыгать то и не нужно. Нужно просто брать элементы массива и засовывать куда тебе надо.
     
    Deonis нравится это.
  11. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Или preg_split, или уже полностью привести формат данных к XML, а не делать гибрид из CSV и XML, или вообще использовать БД. Кстати, почему файл, а не база?
     
  12. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    @TeslaFeo в последнем варианте не нужен мне explode(), я разбивал строку на подстроку и заносил каждую подстроку в переменную, и даже explode использовал, но сейчас другой код пишу.
    Вы коментарии не прочли к коду выше в конце
    Код (Text):
    1. $newbln=($num20 + $bln);  // итог, это число нужно расположить между тегов <User></User>  перед этим удалив содержимое тега.в txt файле ok.txt
    --- Добавлено ---
    вроде просто, но не получается )
     
  13. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    я набросал код(выше), который заносит в переменную число между <User></User> и суммирование выполняет +20.
    Полученный ответ уже есть, его нужно в теги вставить, удалив старое число.
    Сейчас следующее выполнить нужно :
    1) удаляем данные в txt между тегами <User></User>
    2)Сохраняем txt с свободным тегом без данных, иначе нужно строку с этим тэгом всю заменять- это не удобно
    3)И вставляем ответ в txt между свободными тегами <User></User>
    Если не сложно покажите как это осуществить ? С комментариями, если можно )))
     
  14. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    фух... придумал,написал так
    Код (Text):
    1.  
    2. $str = file_get_contents ( 'ok.txt' );
    3. $str = str_replace ( '<'.$name.'>'.$b.'</'.$name.'>', '<'.$name.'>'.$newb.'</'.$name.'>', $str );
    4. file_put_contents ( 'ok.txt', $str );
     
  15. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    Беспокоит вопрос, слышал, что при одновременной записи данных в txt фаил несколькими пользов-ми, данные в txt могут стираться, ошибки могут быть, это правда?
     
  16. Fox-

    Fox- Активный пользователь

    С нами с:
    11 янв 2018
    Сообщения:
    94
    Симпатии:
    3
    flock() должен помочь, не имею представления, как он работает, как применить...
     
  17. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    открываешь файл, в цикле пытаешься сделать блокировку. если блокировка успешная - почитал-записал, снял блокировку, умер. Если блокировка не успешная - немного поспать и ещё раз попробовать заблокировать. Если число попыток блокировки превысило разумный предел - тут уже по ситуации: вэб закончишь ответом ошибкой, а даемон же может и ещё немного потыркаться в блокировку. Главное селать неблокирующую блокировку, а то заблокируешь выполнение скрипта до успешной блокировки.