Sed для удаления подчеркивания и продвижения персонажа

Все объекты гарантированно имеют метод .equals(), поскольку Object содержит метод, .equals(), который возвращает логическое значение. Задача подкласса переопределять этот метод, если требуется дополнительное определение определения. Без него (т. Е. Используя ==) только адреса памяти проверяются между двумя объектами для равенства. String переопределяет этот метод .equals() и вместо использования адреса памяти возвращает сравнение строк на уровне символа для равенства.

Ключевое замечание состоит в том, что строки хранятся в одном пуле, поэтому после создания строки он всегда хранится в программе по тому же адресу. Строки не меняются, они неизменяемы. Вот почему это плохая идея использовать регулярную конкатенацию строк, если у вас есть серьезное количество обработки строк. Вместо этого вы будете использовать предоставленные классы StringBuilder. Помните, что указатели на эту строку могут измениться, и если вам было интересно увидеть, были ли два указателя одинаковыми ==, это был бы прекрасный способ. Строки сами не делают.

7
задан radman 29 June 2010 в 01:36
поделиться

3 ответа

sed -re 's,[a-z]+(_[a-z]+)+,&_,g' -e 's,_([a-z]),\u\1,g'

Объяснение:

Это команда sed с двумя выражениями (каждое в кавычках после -e.) s,,,g - это глобальная подстановка. Обычно ее можно увидеть с косой чертой вместо запятых, но я думаю, что это легче читать, когда в шаблонах используются обратные косые черты (и нет запятых). Запятая g (глобальная) означает, что эта подстановка применяется ко всем совпадениям в каждой строке, а не только к первому.

Первое выражение добавляет знак подчеркивания к каждой лексеме, состоящей из строчного слова ([a-z]+), за которым следует ненулевое количество строчных слов, разделенных знаками подчеркивания ((_[a-z]+)+). Мы заменим это на &_, где & означает "все, что совпало", а _ - это просто буквальное подчеркивание. В целом, это выражение означает, что нужно добавить знак подчеркивания в конец каждого токена, разделенного нижним регистром (underscore_separated_lowercase_token).

Второе выражение соответствует шаблону _([a-z])), где все между ( и ) является группой захвата. Это означает, что в дальнейшем мы можем ссылаться на нее как на \1 (потому что это первая группа захвата. Если бы их было больше, они были бы \2, \3 и так далее). Итак, мы говорим, что нужно подобрать строчную букву, следующую за подчеркиванием, и запоминаем букву.

Мы заменяем ее на \u\1, которая является буквой, которую мы только что запомнили, но сделали прописной с помощью \u.

Этот код не делает ничего умного для того, чтобы избежать отбрасывания #include строк и т.п.; он заменяет каждый случай строчной буквы, следующей за подчеркиванием, на ее прописной эквивалент.

5
ответ дан 6 December 2019 в 23:00
поделиться

Несколько лет назад я успешно преобразовал устаревшую кодовую базу 23-летней давности из 300 000 LOC в camelCase. Прошло всего два дня. Но было несколько затяжных аффектов, на устранение которых ушло несколько месяцев. И это очень способ рассердить других программистов.

Я считаю, что простой, тупой подход, похожий на sed, имеет свои преимущества. Насколько мне известно, инструменты на основе IDE и т.п. не могут:

  • изменить код не , скомпилированный с помощью # ifdef
  • изменить код в комментариях

И унаследованный код должен был быть поддерживается на нескольких разных платформах компилятора / ОС (= множество #ifdef).

Главный недостаток тупого, похожего на sed подхода заключается в том, что строки (например, ключевые слова) могут быть случайно изменены. И я сделал это только для C; C ++ может быть еще одним котлом с рыбой.

Есть около пяти этапов:

1) Generate a list of tokens that you wish to change, and manually edit.
2) For each token in that list, determine the new token.
3) Apply these changes to your code base.
4) Compile.
5) Double-check via a manual diff, and do a final clean-up.

Для шага 1, чтобы сгенерировать список токенов, которые вы хотите изменить, команда:

cat *.[ch] | sed 's/\([_A-Za-z0-9][_A-Za-z0-9]*\)/\nzzz \1\n/g' | grep -w zzz | sed 's/^zzz //' | grep '_[a-z]' | sort -u > list1

создаст в list1:

st_atime
time_t
...

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

Следующим шагом 2 является создание сценария для внесения изменений.Например, команда:

cat list1 | sed 's/\(.*\)/glob_sub "\\<\1\\>" xxxx_\1/;s/\(xxxx_.*\)_a/\1A/g;s/\(xxxx_.*\)_b/\1B/g;s/\(xxxx_.*\)_a/\1C/g;s/\(xxxx_.*\)_t/\1T/g' | sed 's/zzz //' > list2

изменит _a, _b, _c и _t на A, B, C и T, чтобы произвести:

glob_sub "\<st_atime\>" xxxx_stAtime
glob_sub "\<time_t\>" xxxx_timeT

Вам просто нужно расширить его, чтобы охватить d, e, f,. .., x, y, z,

Я полагаю, вы уже написали что-то вроде 'glob_sub' для своей среды разработки. (Если нет, откажитесь сейчас.) Моя версия (csh, Cygwin) выглядит так:

#!/bin/csh
foreach file (`grep -l "$1" */*.[ch] *.[ch]`)
  /bin/mv -f $file $file.bak
  /bin/sed "s/$1/$2/g" $file.bak > $file
end

(Некоторые из моих sed не поддерживают параметр --in-place, поэтому я должен использовать mv.)

Третий шаг - применить этот скрипт в list2 к вашей базе кода. Например, в csh используйте список источников 2 .

Четвертый шаг - компиляция. Компилятор будет (надеюсь!) Возражать против xxxx_timeT . На самом деле, вероятно, следует возразить только против timeT , но дополнительный xxx_ добавляет страховку. Итак, для time_t вы ошиблись. Отмените его, например,

glob_sub "\<xxxx_timeT\>" time_t

Пятый и последний шаг - провести ручную проверку ваших изменений с помощью вашей любимой утилиты diff, а затем очистить, удалив все нежелательные префиксы xxx_ . Grepping для "xxx_ также поможет проверить токены в строках. (Действительно, добавление суффикса _xxx, вероятно, является хорошей идеей.)

3
ответ дан 6 December 2019 в 23:00
поделиться

Рассмотрите возможность использования sed для поиска и замены всего такого текста. Без токенизатора C ++ для распознавания идентификаторов (и, в частности, ваших идентификаторов, а не идентификаторов в стандартной библиотеке, например), вы облажались . push_back переименовывается в pushBack_. map :: insert в map :: insert_. сопоставить с map_. basic_string в basicString_. printf на printf_ (если вы используете библиотеки C) и т.д.

Я не знаю ни одного существующего инструмента для автоматического переименования some_var_name в someVarName_ без проблем, описанных выше. Люди проголосовали за этот пост, вероятно, потому, что не поняли, что я имел в виду. Я не говорю, что sed не может этого сделать, я просто говорю, что он не даст вам того, что вы хотите , чтобы просто использовать его как есть. Парсеру нужна контекстная информация, чтобы делать это правильно, иначе он заменит гораздо больше вещей, которых не должен, чем должен.

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

Однако Visual AssistX (который может опционально заменять экземпляры в документации) или любой другой инструмент рефакторинга, способный грамотно переименовывать идентификаторы для каждого экземпляра, в котором они встречаются, по крайней мере, таким образом значительно облегчает бремя рефакторинга кода.Если у вас есть символ с именем some_var_name и на него есть ссылки в тысяче разных мест в вашей системе, с VAssistX вы можете просто использовать одну функцию переименования, чтобы грамотно переименовать все ссылки (это не простой текстовый поиск и замена). Ознакомьтесь с функциями рефакторинга Visual Assist X .

Реорганизация сотни переменных таким образом с помощью VAX может занять от 15 минут до получаса (быстрее, если вы используете горячие клавиши), но, безусловно, лучше использовать текстовый поиск и заменять на sed, как описано в другом ответе, и имея заменены все виды кода, которые не подлежат замене.

[субъективно] Кстати: подчеркивания по-прежнему не подходят в случае с верблюдами, если вы спросите меня. В соглашении об именах lowerCamelCase следует использовать lowerCamelCase. По этому поводу есть много интересных статей, но, по крайней мере, ваше соглашение согласовано. Если это согласованно, то это огромный плюс в отличие от чего-то вроде fooBar_Baz, которое пишут некоторые тупые кодеры, которые думают, что это каким-то образом упрощает создание особых исключений из правила. [/ Subjective]

3
ответ дан 6 December 2019 в 23:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: