toScreamingSnakeCase method

String toScreamingSnakeCase()

Converts camelCase or PascalCase to SCREAMING_SNAKE_CASE.

Handles common cases like acronyms and digit boundaries.

Examples:

  • camelCase → CAMEL_CASE
  • HTTPRequest → HTTP_REQUEST
  • myURLId2Parser → MY_URL_ID_2_PARSER
  • _privateField → _PRIVATE_FIELD

Implementation

String toScreamingSnakeCase() {
  if (isEmpty) return this;

  // Preserve leading underscores (e.g., Dart private members).
  final leading = RegExp('^_+').stringMatch(this) ?? '';
  var result = substring(leading.length);

  // Split lower/digit -> Upper (e.g., "fooBar" -> "foo_Bar", "v2X" -> "v2_X").
  result = result.replaceAllMapped(
    RegExp('([a-z0-9])([A-Z])'),
    (match) => '${match[1]}_${match[2]}',
  );

  // Split acronym -> Word (e.g., "HTMLParser" -> "HTML_Parser").
  result = result.replaceAllMapped(
    RegExp('([A-Z]+)([A-Z][a-z])'),
    (match) => '${match[1]}_${match[2]}',
  );

  // Separate letters and digits both ways (e.g., "ID10T" -> "ID_10_T").
  result = result.replaceAllMapped(
    RegExp('([A-Za-z])([0-9])'),
    (match) => '${match[1]}_${match[2]}',
  );
  result = result.replaceAllMapped(
    RegExp('([0-9])([A-Za-z])'),
    (match) => '${match[1]}_${match[2]}',
  );

  // Normalize separators and scream.
  result = result.replaceAll(RegExp('_+'), '_');
  return leading + result.toUpperCase();
}