Чи погано розміщувати текстові маркери всередині рядків? Чи є альтернатива?


10

Я працюю з масивними струнами, які потребують багато маніпуляцій.

Наприклад, я можу створити такий рядок:

Частина 1
Човен

Розділ A
Програмування

Частина 2.
Роздільні човни для програмування.

Розділ AA
Записи SQL.

Рядок був би занадто великим, щоб вручну перевірити кожну його частину. Тепер мені потрібно splitце stringв stringlistрозділи та частини. Я можу придумати два варіанти:

Регулярний вираз:

QStringList sl = s.split(QRegularExpression("\n(?=Part [0-9]+|Section [A-Z]+)"));

Схоже, це має спрацювати, але іноді винятки прослизають (IE: Section SQL Entriesпомилково розколоться)

Інакше я можу зробити маркер, коли генерую початковий рядок:

🚤💻 Частина 1
човен

EРозділ A
Програмування

Art Частина 2 Роздільні
човни для програмування.

EРозділ
SQL Записи розділу AA .

Що означає, що розділити рядок стане легко:

QStringList sl = s.split("🚤💻"));

Щось мені каже, що жодне з них не є гарним стилем чи практикою програмування, але я до цього моменту не обговорював це і не знайшов альтернативи.

  • Якби ви були моїм керівником проекту, чи прийняли б ви один із цих методів?
  • Якщо ні, то що б ви запропонували зробити як найкращу практику?

6
Якщо ваша програма знає, де розмістити ці маркери, чому б не сформувати розділи як окремі рядки для початку?
Яків Райхле

Я не думаю, що користувач маркер, який не добре перекладається у вашому поточному кодуванні, не є хорошою ідеєю.
Tulains Córdova

2
фактичні використовувані символи в значній мірі не мають значення, те, що зміниться, - це граматика того, що ви намагаєтеся розібрати
jk.

4
@Akiva Ви впевнені в хіті виступу? Ви працюєте з однаковою кількістю даних у будь-якому випадку, я сумніваюся, що це буде суттєвою різницею. Складіть тисячі функцій в одну функцію, викликайте її в циклі і зробіть деякі вимірювання.
Яків Райхле

2
@Akiva Отримання та заміна елементів у списку в гіршому випадку має бути порівнянним з розділенням великої рядки.
Яків Райхле

Відповіді:


17

Непогана практика кодування документа вбудована як текст у рядку. Подумайте про розмітку, HTML, XML, JSON, YAML, LaTeX тощо.

Погана практика - це винахід колеса. Замість того, щоб писати власний текстовий процесор, подумайте про використання існуючого стандарту. Існує безліч безкоштовного програмного забезпечення, яке робить для вас більшу частину розбору, і багато з них мають необмежуючу ліцензію, яка дозволяє вам використовувати вказане програмне забезпечення у власному власному програмному забезпеченні.


У моєму випадку я вигадую колесо, якщо те, що я намагаюся зробити, - це створити унікальний перекладач для мови розмітки. Наприклад, один із моїх проектів інтерпретував Latex як SSML, який читається людським вухом: meta.wikimedia.org/wiki/Grants:IdeaLab/… . << У кінці цієї URL-адреси є період, інакше він не працюватиме
Akiva

2
@Akiva Мені доводиться працювати з користувацьким текстовим форматом, розробленим моїм робочим місцем, який буквально відновлює колесо. Я повинен підтримувати 4 аналізатори на 3 мовах (Javascript, Java та Objective-C), і це страшний кошмар . Зробіть правильно зараз і скасуйте цей нестандартний текстовий формат дурниць . Я не можу наголосити достатньо, наскільки величезним кошмаром технічного обслуговування це стане за кілька років вниз. Використовуйте існуючі структуровані формати, XML, JSON тощо.
Chris Cirefice

@ChrisCirefice Чи можете ви навести приклад того, як це кошмар?
Аківа

1
@Akiva Я думаю, що жахливим є той факт, що вам доведеться підтримувати навіть один аналізатор (у моєму випадку декілька та різними мовами). Стандартні формати існують з причини - вони можуть представляти потрібні вам дані - і з вами дуже мало зусиль, оскільки ці парсери були побудовані, вдосконалені та підтримуються. Спеціальний текстовий формат також є надзвичайно спеціалізованими знаннями, тобто зазвичай лише один або два розробники будуть достатньо знайомі з форматом, щоб успішно його підтримувати. Це має говорити багато. Більшість людей знайомі з CML, JSON - мало хто знає власні формати.
Кріс Сірефіс

1
@Akiva Дійсно! Формат розмітки (те, що SE та багато інших сайтів використовують для форматування тексту) є дещо стандартним , як і SQL. Але є багато різних "ароматів" із спеціальними розширеннями (наприклад, SE). Існує стандартна бібліотека, яка розбирає 'ядро', після чого ви розширюєте бібліотеку, якщо хочете отримати додаткові функції. Але створення та підтримка власного форматера було б смішним - декілька вже існують (розмітка, код BB та ін.), Тож навіщо винаходити колесо та підтримувати весь цей код? Може також просто використовувати наявну бібліотеку :)
Chris Cirefice

8

Використання деякого загального роздільника має справно працювати при розділенні великих довільних рядків, але я б рекомендував не використовувати довільний символ. Хтось, хто читає цей рядок як непростий текст, може бути переплутаний, не кажучи вже про проблеми з UTF та незалежно від того, відображається чи ні символ всередині розділів чи ні.

Найважливіша частина цього полягає в тому, що кожен розділ залишається недоторканим, тоді як кожен "заголовок розділу" повинен бути відповідним чином ідентифікований.

Чому б не використовувати загальний розділювач, а зберегти його читабельним? Щось на зразок:

[SECTION]
Part 1
Boat

[SECTION]
Section A
Programming

[SECTION]
Part 2
Partitioning boats for programming.

[SECTION]
Section AA
Section SQL Entries.

Проблема полягає у вирішенні питання про те, яким повинен бути роздільник , оскільки це має бути те, що гарантовано не відображатиме жодного розділу. Ви можете далі визначити його як роздільник , вимагаючи, щоб він був на початку рядка і єдиним текстом у цьому рядку .

Без подальшого знання того, який текст очікується в кожному розділі, важко дати рекомендацію щодо того, який загальний роздільник буде найкращим у цьому випадку.


Мені подобається наголос вашої відповіді на читанні. Рядки генеруються за допомогою скребкування тексту, сформованого користувачем, скажімо, наприклад, мовою розмітки, яка використовується в SE для написання запитань та відповідей. Таким чином, ви можете легко уявити, який тип питань маніпуляції з рядком може ввійти в гру.
Аківа

5

Здається, прийнята відповідь пропустила те, що ви написали в коментарі:

Причина полягає в тому, що для багатьох маніпуляцій, які я роблю, потрібен повний рядок

і наводив це як приклад:

s.replace ("човен", "програмування");

Якщо це те, що ви хочете, це IMHO дійсно погана ідея використовувати деяку "розмітку" або текстовий роздільник для всієї рядка, це завжди має певний ризик втручатися в маніпуляції і не призведе до надійного коду. Особливо, коли ви намагаєтесь почати використовувати регулярні вирази на такій комбінованій рядку, ви, мабуть, зіткнетеся з тими ж проблемами, що спостерігалися при спробі розбору HTLM або XML регулярними виразами .

Тим більше, що ви писали, що може існувати "тисяча [таких маніпуляцій] функцій", цей ризик може стати справжньою проблемою. Навіть якщо ви використовуєте деяку розмітку, наприклад XML, для внутрішнього зберігання списку рядків, вам потрібно переконатися, що маніпуляція буде обробляти лише вміст, а не розмітку, так що це означатиме розділити рядок на частини перед будь-якою обробкою та приєднатись після цього знову - так що ви будете мати високий ризик дати вам погану роботу.

Кращою альтернативою дизайну тут є надання абстрактного типу даних (використовуйте клас, якщо вам подобається), давайте його MyStringListможемо називати та надавати невеликий набір основних операцій, які дозволять вам реалізувати свої "тисячі функцій" з точки зору цих операцій. Наприклад, можуть бути загальні findта replaceоперації, або загальна функціональна mapоперація . Ви також можете додати щось на зразок JoinToStringоперації, якщо вам дійсно потрібен весь список в одній рядку для певних цілей.

Використовуючи ці операції, ваш страх, що код стане складнішим, оскільки "все, що потрібно зробити в циклі for", стає безглуздим, оскільки єдині forцикли, які ви отримуєте, інкапсульовані всередині операцій типу даних. І я б не хвилювався щодо продуктивності, доки ви не матимете реального, вимірюваного впливу на продуктивність (який, я сумніваюся, ви отримаєте, якщо правильно виконати основні операції).


Оновлення, тому що я насправді створив щось подібне. Це дозволяє мені встановити спеціальні дужки, які говорять, <і >, і вона захопить кожен екземпляр тієї рядка, з якої я можу легко видалити екземпляри, які я не хочу, і чисто маніпулювати нею так, як я хочу. Це добре, тому що регулярні вирази самі по собі не обробляють такі підрядки: <boat <programming>>добре там, де є кілька шарів дужок.
Аківа

1

Описаний формат дуже схожий на файли INI:

https://en.wikipedia.org/wiki/INI_file

У цьому випадку розділ додається квадратними дужками [], тому те, що ви описуєте, має сенс, позначаючи розділ якось, щоб додати додаткового значення цьому тексту.


0

Наприклад, я можу створити такий рядок:

Запитання: З чого ви "генеруєте" цей рядок?

Буде , що буде легше маніпулювати?


Рядок генерується із вмісту користувача Datascraping з веб-сайту.
Аківа

1
Це не надійний спосіб отримати дані з веб-сайту, просто тому, що вони змінюються, і все переміщується або повністю зникає. Вам буде набагато краще отримати дані з якогось опублікованого (і тому надійного) API. Крім того, використання багатьох комерційних веб-сайтів спеціально забороняє подібні речі.
Філл В.

Іноді мені не вдається вибрати те, які дані для мене цінні, і тому завжди потрібно перевірити цілісність того, що ти дивишся, або просто простий компроміс і сподіваємось на краще. Наприклад: я написав LaTeXдля SSMLперекладача, і одне із запитань є те , що ви можете створити ідентичні зображення з абсолютно іншим кодом, і тому майже неможливо бути послідовним , якщо користувач вибирає бідний або езотеричні способи отримання його формули. Все, що означає наприкінці дня, - це те, що люди, які не користуються належною практикою, не матимуть гідних тлумачень своїх сценаріїв.
Аківа
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.