Хобрук: Ваш путь к мастерству в программировании

Изменение текста в файле .txt и создание нового выходного файла в MATLAB

Заранее прошу прощения, если название покажется немного неправильным. Мне было трудно решить, как именно я должен назвать это. В любом случае, в основном то, что я делаю сейчас, — это полностью домашняя работа, связанная с низкоуровневыми операциями ввода-вывода. Для моего одного задания я дал два файла .txt, один из которых содержит список адресов электронной почты, а другой включает список участников, которые больше не должны были быть в списке электронной почты. Что мне нужно сделать, так это удалить электронные письма участников из второго списка. Кроме того, в файлах .txt могут быть неприятные сюрпризы. Я должен очистить электронные письма и удалить все нежелательные знаки препинания после электронных писем, такие как точки с запятой, запятые и пробелы. Кроме того, мне нужно перевести весь текст в нижний регистр. Я борюсь с этой проблемой несколькими способами (я не совсем уверен, как заставить мой файл писать то, что мне нужно, в моем выводе), но сейчас моя главная задача - вывести сообщение об отказе от подписки в правильном заказ. Сортировка, похоже, не работает.

Вот несколько тестовых случаев:

Test Cases
unsubscribe('Grand Prix Mailing List.txt', ...
              'Unsubscribe from Grand Prix.txt')
     => output file named 'Grand Prix Mailing List_updated.txt' that looks
        like 'Grand Prix Mailing List_updated_soln.txt'
     => output file named 'Unsubscribe from Grand Prix_messages.txt' that 
        looks like 'Unsubscribe from Grand Prix_messages_soln.txt'

Оригинальный список рассылки

Grand Prix Mailing List:
[email protected], 
[email protected] 
[email protected];
[email protected]
[email protected],
[email protected]
[email protected]
[email protected];
[email protected]
[email protected]
[email protected]

Люди, которые как нет:

MARIO PLUMBER; 
bowser koopa 
Luigi Plumber,
Donkey Kong 
King BOO;
Princess Peach

Как это должно выглядеть после:

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

Мой вывод файла:

Mario, you have been unsubscribed from the Grand Prix mailing list.
Luigi, you have been unsubscribed from the Grand Prix mailing list.
Bowser, you have been unsubscribed from the Grand Prix mailing list.
Princess, you have been unsubscribed from the Grand Prix mailing list.
King, you have been unsubscribed from the Grand Prix mailing list.
Donkey, you have been unsubscribed from the Grand Prix mailing list.

Итак, Amro был достаточно любезен, чтобы предоставить решение, хотя оно немного превосходит то, что я знаю прямо сейчас. Моя главная проблема сейчас заключается в том, что когда я вывожу сообщение об отмене подписки, мне нужно, чтобы оно было в том же порядке, что и исходный список адресов электронной почты. Например, хотя Баузер был в списке жалоб перед Луиджи, в сообщении об отказе от подписки Луиджи должен появиться перед ним.

Вот мой исходный код:

function[] = unsubscribe(email_ids, member_emails)
    Old_list = fopen(email_ids, 'r'); %// opens my email list
    Old_Members = fopen(member_emails, 'r'); %// Opens up the names of people who want to unsubscribe
    emails = fgets(Old_list); %// Reads first line of emails
    member_emails = [member_emails]; %// Creates an array to populate
while ischar(emails) %// Starts my while loop
%// Pulls out a line in the email
    emails = fgets(Old_list);
%// Quits when it sees this jerk
    if emails == -1
        break;
    end

%// I go in to clean stuff up here, but it doesn't do any of it. It's still in the while loop though, so I am not sure where the error is
proper_emails = lower(member_emails); %// This is supposed to lowercase the emails, but it's not working
unwanted = findstr(member_emails, ' ,;');
member_emails(unwanted) = '';
member_emails = [member_emails, emails];
end

while ischar(Old_Members) %// Does the same for the members who want to unsubscribe
    names = fgetl(member_emails);
    if emails == -1
        break
    end
proper_emails = lower(names); %// Lowercases everything
unwanted = findstr(names, ' ,;');
names(unwanted) = '';
end

Complainers = find(emails);

New_List = fopen('Test2', 'w'); %// Creates a file to be written to
fprintf(New_List, '%s', member_emails); %// Writes to it
Sorry_Message = fopen('Test.txt', 'w');
fprintf(Sorry_Message, '%s', Complainers);

%// Had an issue with these, so I commented them out temporarily
%// fclose(New_List);
%// fclose(Sorry_Message);
%// fclose(email_ids); 
%// fclose(members);

end

  • У вас есть список имен, которые идут с каждым адресом электронной почты? Ваше решение обращается к каждому человеку по имени, но предоставленный вами образец входных данных не включает их. 14.10.2014
  • @rayryeng Я знал, что что-то забыл. Добавил извиняюсь! 14.10.2014
  • Еще немного непонятно. Каков формат текстового файла? Сначала появляется имя, а затем адрес электронной почты? Ваш образец ввода все еще сбивает с толку. 14.10.2014
  • Есть список адресов электронной почты, затем отдельный список адресов электронной почты. 14.10.2014

Ответы:


1

Ниже приведена моя реализация проблемы. Код комментируется на каждом этапе и должен быть простым для понимания. Я использую регулярные выражения, когда могу, потому что это то, в чем они хороши... Также обратите внимание, что у меня нет циклов в коде :)

отписаться.м

function unsubscribe(mailinglist_file, names_file)

    %%
    % read list of names of those who want to unsubscribe
    names = read_file(names_file);

    % break names into first/last parts
    first_last = regexp(names, '(\w+)\s+(\w+)', 'tokens', 'once');
    first_last = vertcat(first_last{:});

    % build email handles (combination of initials + name + domain)
    emails_exclude = strcat(cellfun(@(str) str(1), first_last(:,1)), ...
        first_last(:,2), '[email protected]');

    %%
    % read emails in mailing list
    emails = read_file(mailinglist_file);

    % update emails by removing those who wish to unsubscribe
    emails(ismember(emails, emails_exclude)) = [];

    %%
    % write updated mailing list
    [~,fName,fExt] = fileparts(mailinglist_file);
    fid = fopen([fName '_updated' fExt], 'wt');
    fprintf(fid, '%s\n', emails{:});
    fclose(fid);

    % write list of names removed
    % capilaize first letter of first name
    first_names = cellfun(@(str) [upper(str(1)) str(2:end)], ...
        first_last(:,1), 'UniformOutput',false);
    msg = strcat(first_names, ...
        ', you have been unsubscribed from the mailing list.');
    fid = fopen([fName '_messages' fExt], 'wt');
    fprintf(fid, '%s\n', msg{:});
    fclose(fid);

end

function C = read_file(filename)
    % read lines from file into a cell-array of strings
    fid = fopen(filename, 'rt');
    C = textscan(fid, '%s', 'Delimiter','');
    fclose(fid);

    % clean up lines by removing trailing punctuation
    C = lower(regexprep(C{1}, '[,;\s]+$', ''));
end

Учитывая следующие текстовые файлы:

список.txt

[email protected], 
[email protected] 
[email protected];
[email protected]
[email protected],
[email protected]
[email protected]
[email protected];
[email protected]
[email protected]
[email protected]

имена.txt

MARIO PLUMBER; 
bowser koopa 
Luigi Plumber,
Donkey Kong 
King BOO;
Princess Peach

Вот что я получаю при запуске кода:

>> unsubscribe('list.txt', 'names.txt')

list_messages.txt

Mario, you have been unsubscribed from the mailing list.
Bowser, you have been unsubscribed from the mailing list.
Luigi, you have been unsubscribed from the mailing list.
Donkey, you have been unsubscribed from the mailing list.
King, you have been unsubscribed from the mailing list.
Princess, you have been unsubscribed from the mailing list.

list_updated.txt

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
14.10.2014
  • Похоже, это целая куча вещей, которые я не знаю, как использовать. Regex является одним из них. Я не знаю, что такое '\w+'. Я никогда не использовал файловые части. Нас только учили как fprintf или просто открывать и писать в него. Я все равно протестировал его, чтобы увидеть, смогу ли я использовать его структуру и изменить его части на то, что я знаю, как это сделать, но он выдает ошибку в строке двенадцать emails_exclude = strcat(cellfun(@(str) str(1), first_last(:,1)), first_last(:,2), '[email protected]'); Пишет, что превышен размер матрицы. Я ценю помощь, кстати. 14.10.2014
  • @JessicaMarie: regexp или регулярные выражения — это те вещи, которые вы действительно хотите изучить. Они могут быть очень полезны при работе с текстом в полусвободной форме. В Интернете есть хороший учебник: regexone.com. Строка, которую вы выделили, строит адрес электронной почты из имени/фамилии: я извлекаю первую букву из имени, затем добавляю фамилию и доменную часть. strcat может обрабатывать смешанный ввод как с массивами ячеек, так и с обычными символами. Я предлагаю вам запустить код в отладчике и выполнять его построчно, проверяя переменные на каждом этапе. 14.10.2014
  • fileparts — это функция, используемая для разделения пути/имени/расширения полного имени файла. Таким образом, при вводе типа C:\path\to\file.txt он будет разделять его на C:\path\to как путь, file как имя и .txt как расширение. Я использовал эту функцию, чтобы получить исходное имя файла списка рассылки и добавить к нему часть _updated. 14.10.2014
  • +1 - Всегда люблю твои посты, Амро :). Также спасибо за ссылку на regexone. Пришло время освежить мой regex, так как многие вопросы здесь могут быть красноречиво решены с его помощью. 14.10.2014
  • @Amro Я отлаживал его и пытался изменить, используя то, что знаю, но строка, которую я выделил, строка emails_exclude, выдавала ошибки. Каким-то образом вы проиндексировали за пределы, но я не совсем уверен, как вы это сделали, в первую очередь потому, что я не понимаю формат. 14.10.2014
  • @JessicaMarie: если бы мне пришлось угадывать, я бы сказал, что у вас, вероятно, есть список имен, которые не соблюдают формат firstName LastName (плюс любые знаки препинания в конце), по одному на строку. Если это так, вам придется настроить регулярное выражение, чтобы оно соответствовало всем возможным случаям... Помимо того, что используемое здесь регулярное выражение действительно простое, вы можете заменить его чем-то другим; идея состоит в том, чтобы разбить строку на части имени и фамилии, разделенные пробелами (обратите внимание, что я применяю ее к массиву ячеек строк, поэтому вам придется иметь дело с этим циклом, если вам нужно) 14.10.2014
  • Неа .-. Это именно тот файл, который я скопировал сюда. Так что я не слишком уверен, что происходит. Я попытался разбить его с помощью strtok, но он тоже жаловался. Может быть, я что-то пропустил. И я смутно понимаю выражение регулярного выражения, это strcat кажется мне странным. 14.10.2014
  • @rayryeng: спасибо. если вы хотите проверить свои навыки регулярных выражений, я помню, что видел несколько интересных задач на Cody с действительно умные решения с использованием регулярных выражений. 14.10.2014
  • @JessicaMarie: я только что прочитал ваше редактирование вопроса и вижу, что вы включили строку заголовка в начало файла списка рассылки (например, Grand Prix Mailing List:). Это тоже часть файла? 14.10.2014
  • Нет. Я просто сделал это, чтобы объяснить, какой текст у меня был под заголовком. Они все просто список имен. никаких лишних пробелов между ними или чего-то еще. Одно имя и фамилия в строке. 14.10.2014
  • @JessicaMarie: трудно сказать, что не так в вашем случае. Я предлагаю вам проверить переменные, участвующие непосредственно перед строкой нарушения (например, first_last должен быть массивом ячеек Nx2 строк, где 1-й столбец — это имена, а 2-й столбец содержит фамилии). 14.10.2014
  • Я нашел ошибку. Наш порядок ввода другой. Похоже, он работает правильно, за исключением того, что он не пишет в файл «Отписаться от Grand Prix_messages.txt», но я думаю, что могу это исправить сам. Большое спасибо :) 14.10.2014
  • Видимо не могу разобраться. Любые предложения/советы? Я чувствую, что это решение слишком выше моего понимания, чтобы правильно манипулировать им. 14.10.2014
  • @JessicaMarie: хорошо, как насчет сейчас? 14.10.2014
  • Клянусь, я сделал то же самое, только где-то ошибся. Это работает, чем вы :) Еще один вопрос, прежде чем я отлаживаю чертовски код, как мне изменить решение для сообщения, чтобы оно возвращало ... X был отписан в том же порядке, что и исходный список рассылки. Например, он должен сказать, что Луиджи отписался от списка, прежде чем сказать об этом Боузеру. Я думал что-то об индексации ячеек. Клянусь, я ненавижу домашние задания, которые они нам дают. Мы едва перевалили половину того дерьма, которое нам нужно для задач. 14.10.2014
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..