Использование магических строк или констант при обработке знаков препинания?
-
05-07-2019 - |
Вопрос
Мы выполняем большую лексическую обработку с произвольными строками, которые включают произвольную пунктуацию.Я разделился во мнениях относительно того, использовать ли магические символы / строки или символические константы.
Приведенные примеры следует рассматривать как не зависящие от языка, хотя большинство из них относятся к Java.
Есть четкие примеры, когда пунктуация играет семантическую роль и должна быть идентифицирована как константа:
File.separator
нет "/"
или "\\"
;// несложно, так как это зависит от операционной системы
и я пишу XML_PREFIX_SEPARATOR = ":"
;
Однако, допустим, мне нужно заменить все примеры ""
с пустой строкой `.Я могу писать:
s = s.replaceAll("\"\"", "");
или
s = s.replaceAll(S_QUOT+S_QUOT, S_EMPTY);
(Я определил все распространенные знаки препинания как S_FOO (строка) и C_FOO (символ))
В пользу магических строк / символов:
- Это короче
- Читать (иногда) - это естественно
- Именованные константы могут быть вам незнакомы (
C_APOS
против'\''
)
В пользу констант
- Сложнее делать опечатки (например,контраст
"''" + '"'
сS_APOS+S_APOS + C_QUOT
) - Это устраняет проблемы с экранированием, Если регулярное выражение должно быть
"\\s+"
или"\s+"
или"\\\\s+"
? - Легко выполнить поиск по коду на предмет пунктуации
(Этому есть предел - я бы не стал писать регулярные выражения таким образом, даже несмотря на то, что синтаксис регулярных выражений является одной из наиболее когнитивно дисфункциональных частей всего программирования.Я думаю, нам нужен лучший синтаксис.)
Решение
Если определения могут меняться со временем или между установками, я склонен помещать эти вещи в файл конфигурации и собирать информацию при запуске или по запросу (в зависимости от ситуации). Затем предоставьте статический класс с интерфейсом только для чтения и очистите имена в свойствах для предоставления информации системе.
Использование может выглядеть следующим образом:
s = s.replaceAll(CharConfig.Quotation + CharConfig.Quotation, CharConfig.EmtpyString);
Другие советы
Для общей обработки строк, Я бы не стал использовать специальные символы.Пробел всегда будет пробелом, и просто читать (и писать!) более естественно!:
s.replace("String", " ");
Чем:
s.replace("String", S_SPACE);
Я бы с особой осторожностью использовал такие вещи, как "\ t", например, для представления табуляций, поскольку их нелегко отличить от пробелов в строке.
Что касается таких вещей, как XML_PREFIX_SEPARATOR
или FILE_SEPARATOR
, Вероятно, вам никогда не придется иметь дело с подобными константами, поскольку вы должны использовать библиотеку, которая сделает эту работу за вас.Например, вы не должны писать от руки: dir + FILE_SEPARATOR + filename
, но скорее буду звонить: file_system_library.join(dir, filename)
(или любой другой эквивалент, который вы используете).
Таким образом, у вас будет не только ответ на такие вещи, как константы, но и гораздо лучшая обработка различных крайних случаев, о которых вы, вероятно, сейчас не думаете