J'ai quelques chaînes, saisies par les utilisateurs, qui peuvent ressembler à ceci:Comment diviser cette chaîne
- ++ 7
- 7 ++
- 1 ++ 7
- 1 + 7
- 1 ++ 7 ++ 10 + 15 + 20 + 30 ++
Ce sont à dire:
- Tout jusqu'au 7
- Tout de 7 ans et plus
- 1 et 7 et tout inbetween
- 1 et 7 seulement
- 1 à 7, 10 à 15, 20 et 30 et au-dessus
J'ai besoin d'analyser ces chaînes dans les plages réelles. C'est à dire que j'ai besoin de créer une liste d'objets de type Range qui ont un début et une fin. Pour les items simples, je mets simplement le début et la fin à la même chose, et pour ceux qui sont au-dessus ou au-dessous, je mets le début ou la fin à zéro. Par exemple, pour le premier, j'aurais une plage qui a été définie sur null et la fin définie sur 7.
J'ai actuellement une sorte de méthode désordonnée utilisant une expression régulière pour faire cette division et analyse et je veux simplifier il. Mon problème est que je dois diviser sur + d'abord, puis sur ++. Mais si je divise le + en premier, alors les instances ++ sont ruinées et je finis avec un désordre.
En regardant ces chaînes, il devrait être vraiment facile de les analyser, je ne peux pas trouver une façon intelligente de le faire. Il doit juste être un moyen plus facile (plus propre, plus facile à lire). Impliquant probablement un concept facile que je viens pas entendu parler avant: P
L'expression régulière ressemble à ceci:
private readonly Regex Pattern = new Regex(@" ([+]{2,})?
([^+]+)
(?:
(?: [+]{2,} [^+]*)*
[+]{2,} ([^+]+)
)?
([+]{2,})? ", RegexOptions.IgnorePatternWhitespace);
qui est ensuite utilisé comme ceci:
public IEnumerable<Range<T>> Parse(string subject, TryParseDelegate<string, T> itemParser)
{
if (string.IsNullOrEmpty(subject))
yield break;
for (var item = RangeStringConstants.Items.Match(subject); item.Success; item = item.NextMatch())
{
var startIsOpen = item.Groups[1].Success;
var endIsOpen = item.Groups[4].Success;
var startItem = item.Groups[2].Value;
var endItem = item.Groups[3].Value;
if (endItem == string.Empty)
endItem = startItem;
T start, end;
if (!itemParser(startItem, out start) || !itemParser(endItem, out end))
continue;
yield return Range.Create(startIsOpen ? default(T) : start,
endIsOpen ? default(T) : end);
}
}
Cela fonctionne, mais je ne pense pas que ce soit particulièrement lisible ou maintenable. Par exemple changer les '+' et '++' en ',' et '-' ne serait pas si trivial à faire.
avec ',' et '-' vous diviser par', ', puis par' -' (en supposant pas de chiffres négatifs). Comme vous l'avez dit, un simple 'Replace (" ++ "," - ")' rendra le code trivial, même si c'est un peu hacky. – Kobi
Donc 9 +++ 7 (de 9 et plus et 7) est invalide? –
@Bart: Eh bien, le code que j'ai maintenant permettrait en fait n'importe quel nombre de ++ tant qu'il y en a 2 ou plus. @Kobi: Cela fonctionnerait avec les nombres, mais cela doit fonctionner pour "n'importe quoi". Plus important, cela doit fonctionner pour les dates et pour les chaînes qui peuvent inclure, et -. Donc je suppose que c'est pourquoi ils ont choisi d'utiliser + et ++ ici. – Svish