Complex.fromString constructor

Complex.fromString(
  1. String input
)

Factory to create a complex number from a representation in String.

Supports common formats such as: “3+4i”, “-5,” “2i,” “-i.” Throws FormatException if the string is not recognized.

Implementation

factory Complex.fromString(String input) {
  // Rimuovi spazi per semplificare la regex.
  final inputTrimmed = input.replaceAll(' ', '');

  if (inputTrimmed.isEmpty) {
    throw FormatException('La stringa non può essere vuota.');
  }

  // Regex robust to capture all common forms:
  // (SignOp1? RealPart?) (SignoOp2 PureImaginary i) | (SignOp1? SignOp1? PartImaginary) | (SignOp1? RealPart)
  //
  // 1. Group 1 (Real Part): ^([+-]?\d*\.?\d*)
  // 2. Gruppo 2 (Signo Immaginary): ([+-])?
  // 3. Gruppo 3 (Immaginary Part ): (\d*\.?\d*)
  // 4. Marker 'i' o 'j': [iIjJ]?$
  //
  // Captured examples: "3.5-4i", "-3.5+i", "5i", "8", "-i", "+2.5-i"
  /*final regex = RegExp(
    r'^\s*([+-]?\d*\.?\d*)\s*([+-])\s*(\d*\.?\d*)?[iI]$', // Caso a+bi o -a-bi
    caseSensitive: false,
  );*/

  final regexSimple = RegExp(
    r'^\s*([+-]?\d*\.?\d*)[iI]$', // Casw bi o -bi (pure imaginary)
    caseSensitive: false,
  );

  final regexReal = RegExp(
    r'^\s*([+-]?\d*\.?\d*)$', // Caso a o -a (reale puro)
    caseSensitive: false,
  );

  // Case management "i", "-i", "+i"
  if (inputTrimmed.toLowerCase() == 'i' ||
      inputTrimmed.toLowerCase() == '+i') {
    return Complex(0.0, 1.0);
  }
  if (inputTrimmed.toLowerCase() == '-i') {
    return Complex(0.0, -1.0);
  }

  // TENTATIVE 1: Form a+bi, a-bi, -a+bi, -a-bi
  final match = RegExp(
    r'^\s*([+-]?\d*\.?\d*)\s*([+-])\s*(\d*\.?\d*)?[iI]$',
    caseSensitive: false,
  ).firstMatch(inputTrimmed);

  if (match != null) {
    final reStr = match.group(1)!;
    final signStr = match.group(2)!;
    final imValueStr = match.group(3); // Può essere null/vuoto per "i"
    double re;
    if (reStr.isNotEmpty) {
      re = double.parse(reStr);
    } else {
      re = 0.0;
    }
    double im;
    if (imValueStr == null || imValueStr.isEmpty) {
      // Caso 3+i o -5-i: parte immaginaria implicita è 1.
      im = (signStr == '-') ? -1.0 : 1.0;
    } else {
      im = double.parse(imValueStr);
      // Applica il segno trovato
      if (signStr == '-') {
        im = -im;
      }
    }
    return Complex(re, im);
  }

  // TENTATIVE 2: Form bi, -bi (Pure Imagination, es: "5i", "-3.2i")
  final matchSimple = regexSimple.firstMatch(inputTrimmed);
  if (matchSimple != null) {
    // Handling of a single number followed by ‘i’ (excluding the case +/-i handled above)
    final imStr = matchSimple.group(1)!.replaceAll(RegExp(r'[iI]'), '');
    try {
      return Complex(0.0, double.parse(imStr));
    } catch (_) {
      // Fails if the numeric part is invalid; moves on.
    }
  }

  // TENTATIVE 3: Form a, -a (Reale Puro, es: "5", "-3.2")
  final matchReal = regexReal.firstMatch(inputTrimmed);
  if (matchReal != null) {
    final reStr = matchReal.group(1)!;
    try {
      return Complex(double.parse(reStr), 0.0);
    } catch (_) {
      // Fallisce se la parte numerica è non valida.
    }
  }

  // If no pattern matches
  throw FormatException(
    'Unrecognized complex format. The string format does not accept expressions or functions. Examples are accepted:: "3+4i", "5", "-7i", "2-i", "-4".',
  );
}