Pull to refresh

Универсальная функция toCamelCase() для Java

Reading time3 min
Views9.3K
Сегодня мне понадобилось перевести строку произвольного содержания в camelCase.
В интернете в основном встретились узкоспециализированные методы, которые либо переводят только имена констант (по соглашениям Java, SOME_JAVA_NAMING_CONVENTION_CONST), либо только фразы, разделенные пробелами.
Мне этого категорически не хватало, нужна была бОльшая универсальность.

Как и подобает любому уважающему себя велосипедисту, я начал писать свой алгоритм, и немного увлёкся. Очнувшись от кода, я обнаружил, что функция переводит любые мною скормленные строки в нормальный camelCase или CamelCase.
Единственное, что она не делает — не запрещает цифры в начале получившейся строки (для соглашений JNC), но мне это и не нужно было (при необходимости дописывается одной строкой кода — пополнением ко второму, вложенному, условию).

Что получилось можете увидеть под катом.


Функция принимает два аргумента — собственно строку, и флаг, указывающий писать результат с большой буквы (недо-camelCase).
Делает она всё это за один проход. Код присыпан комментариями для новичков (кому и пишется эта шпаргалка).
При жалении второй аргумент можно безболезненно откусить.
Так же практически без изменений алгоритм портируется на javascript и C#.

	/**
	 * Возвращает отформатированную в виде camelCase (или CamelCase) строку.
	 *
	 * @param string               Исходная строка
	 * @param firstWordToLowerCase Начинать ли искомую строку с маленького символа (lowercase).
	 */
	public static String toCamelCase(String string, boolean firstWordToLowerCase) {
		char currentChar, previousChar = '\u0000'; // Текущий и предыдущий символ прохода
		StringBuilder result = new StringBuilder(); // Результат функции в виде строкового билдера

		boolean firstLetterArrived = !firstWordToLowerCase; // Флаг, отвечающий за написание первого символа результата в lowercase
		boolean nextLetterInUpperCase = true; // Флаг, приказывающий следующий добавляемый символ писать в UPPERCASE

		// Проходимся по всем символам полученной строки
		for (int i = 0; i < string.length(); i++) {
			currentChar = string.charAt(i);

			/* Если текущий символ не цифробуква -
				приказываем следующий символ писать Большим (начать новое слово) и идем на следующую итерацию.
			   Если предыдущий символ это маленькая буква или цифра, а текущий это большая буква -
			    приказываем текущий символ писать Большим (начать новое слово).
			*/
			if (!Character.isLetterOrDigit(currentChar) || (
					((Character.isLetter(previousChar) && Character.isLowerCase(previousChar)) || Character.isDigit(previousChar)) &&
					Character.isLetter(currentChar) && Character.isUpperCase(currentChar))
					) {
				nextLetterInUpperCase = true;
				if (!Character.isLetterOrDigit(currentChar)) {
					previousChar = currentChar;
					continue;
				}
			}

			// Если приказано писать Большую букву, и первая буква уже написана.
			if (nextLetterInUpperCase && firstLetterArrived) {
				result.append(Character.toUpperCase(currentChar));
			}
			else {
				result.append(Character.toLowerCase(currentChar));
			}

			// Устанавливаем флаги.
			firstLetterArrived = true;
			nextLetterInUpperCase = false;
			previousChar = currentChar;
		}

		// Возвращаем полученный результат.
		return result.toString();
	}


Ну и примеры результатов функции
Source string: 'normalCamelCaseName'
Result string: 'normalCamelCaseName'
Result string: 'NormalCamelCaseName' (firstWordToLowerCase = false)
===========================
Source string: 'NotCamelCaseName'
Result string: 'notCamelCaseName'
Result string: 'NotCamelCaseName' (firstWordToLowerCase = false)
===========================
Source string: 'CONSTANT_TO_CAMEL_CASE'
Result string: 'constantToCamelCase'
Result string: 'ConstantToCamelCase' (firstWordToLowerCase = false)
===========================
Source string: 'Text To Camel Case'
Result string: 'textToCamelCase'
Result string: 'TextToCamelCase' (firstWordToLowerCase = false)
===========================
Source string: 'Text to camel case'
Result string: 'textToCamelCase'
Result string: 'TextToCamelCase' (firstWordToLowerCase = false)
===========================
Source string: 'ОтЖиМаЕмСя На ШиФфТе, ДрУзЯфФкИ!:)'
Result string: 'отЖиМаЕмСяНаШиФфТеДрУзЯфФкИ'
Result string: 'ОтЖиМаЕмСяНаШиФфТеДрУзЯфФкИ' (firstWordToLowerCase = false)
===========================
Source string: '-(*&*&%&%$^&^*()Знаков*&^%*(&$препинания… и.нечитаемых-----------знаков^ (Может*90Быть&(*?*?: СКОЛЬКО*?%?:%угодно!'
Result string: 'знаковПрепинанияИНечитаемыхЗнаковМожет90БытьСколькоУгодно'
Result string: 'ЗнаковПрепинанияИНечитаемыхЗнаковМожет90БытьСколькоУгодно' (firstWordToLowerCase = false)
===========================
Source string: 'И, напоследок, русская строка со знаками препинания (локализация!).'
Result string: 'иНапоследокРусскаяСтрокаСоЗнакамиПрепинанияЛокализация'
Result string: 'ИНапоследокРусскаяСтрокаСоЗнакамиПрепинанияЛокализация' (firstWordToLowerCase = false)

Tags:
Hubs:
-9
Comments10

Articles