J'ai une seule chaîne qui contient les paramètres de ligne de commande à passer à un autre exécutable et je dois extraire la chaîne [] contenant les paramètres individuels de la même manière que C # si les commandes avaient été spécifiées sur la ligne de commande. La chaîne [] sera utilisée lors de l'exécution d'un autre point d'entrée d'assemblys via la réflexion.
Existe-t-il une fonction standard pour cela? Ou existe-t-il une méthode préférée (regex?) Pour diviser correctement les paramètres? Il doit gérer les chaînes délimitées par '"' qui peuvent contenir des espaces correctement, donc je ne peux pas simplement diviser sur" ".
Exemple de chaîne:
string parameterString = @"/src:""C:\tmp\Some Folder\Sub Folder"" /users:""[email protected]"" tasks:""SomeTask,Some Other Task"" -someParam foo";
Exemple de résultat:
string[] parameterArray = new string[] {
@"/src:C:\tmp\Some Folder\Sub Folder",
@"/users:[email protected]",
@"tasks:SomeTask,Some Other Task",
@"-someParam",
@"foo"
};
Je n'ai pas besoin d'une bibliothèque d'analyse en ligne de commande, juste un moyen d'obtenir la chaîne [] qui doit être générée.
Mise à jour : j'ai dû modifier le résultat attendu pour qu'il corresponde à ce qui est réellement généré par C # (supprimé les "supplémentaires" dans les chaînes séparées)
la source
Réponses:
En plus de la bonne et pure solution gérée d' Earwicker , il peut être utile de mentionner, par souci d'exhaustivité, que Windows fournit également la
CommandLineToArgvW
fonction de décomposition d'une chaîne en un tableau de chaînes:Vous trouverez un exemple d’appel de cette API à partir de C # et de décompression du tableau de chaînes résultant dans du code managé à l’adresse « Conversion de la chaîne de ligne de commande en Args [] à l’aide de l’API CommandLineToArgvW () ». Voici une version légèrement plus simple du même code:
la source
CommandLineToArgs("foo.exe " + commandLine).Skip(1).ToArray();
Cela m'ennuie qu'il n'y ait pas de fonction pour diviser une chaîne en fonction d'une fonction qui examine chaque caractère. S'il y en avait, vous pourriez l'écrire comme ceci:
Bien qu'ayant écrit cela, pourquoi ne pas écrire les méthodes d'extension nécessaires. Ok, tu m'as parlé de ça ...
Tout d'abord, ma propre version de Split qui prend une fonction qui doit décider si le caractère spécifié doit diviser la chaîne:
Cela peut produire des chaînes vides selon la situation, mais peut-être que ces informations seront utiles dans d'autres cas, donc je ne supprime pas les entrées vides dans cette fonction.
Deuxièmement (et plus banalement) un petit assistant qui coupera une paire de guillemets correspondante du début et de la fin d'une chaîne. C'est plus difficile que la méthode Trim standard - elle ne coupera qu'un seul caractère à chaque extrémité, et elle ne coupera pas d'une seule extrémité:
Et je suppose que vous voudrez aussi des tests. Eh bien, très bien alors. Mais ce doit être absolument la dernière chose! Tout d'abord, une fonction d'assistance qui compare le résultat de la division avec le contenu attendu du tableau:
Ensuite, je peux écrire des tests comme celui-ci:
Voici le test pour vos besoins:
Notez que l'implémentation a la fonctionnalité supplémentaire qu'elle supprimera les guillemets autour d'un argument si cela a du sens (grâce à la fonction TrimMatchingQuotes). Je pense que cela fait partie de l'interprétation normale de la ligne de commande.
la source
char.IsWhiteSpace
place de== ' '
L'analyseur de ligne de commande Windows se comporte comme vous le dites, divisé en espace, sauf s'il y a un guillemet non fermé devant lui. Je recommanderais d'écrire l'analyseur vous-même. Quelque chose comme ça peut-être:
la source
J'ai pris la réponse de Jeffrey L Whitledge et l' ai un peu améliorée.
Il prend désormais en charge les guillemets simples et doubles. Vous pouvez utiliser des guillemets dans les paramètres eux-mêmes en utilisant d'autres guillemets tapés.
Il supprime également les guillemets des arguments car ceux-ci ne contribuent pas aux informations sur les arguments.
la source
La bonne et pure solution gérée par Earwicker n'a pas réussi à gérer des arguments comme celui-ci:
Il a renvoyé 3 éléments:
Voici donc un correctif pour prendre en charge le "quote \" escape \ "quote":
Testé avec 2 cas supplémentaires:
A également noté que la réponse acceptée par Atif Aziz qui utilise CommandLineToArgvW a également échoué. Il a renvoyé 4 éléments:
J'espère que cela aidera quelqu'un à la recherche d'une telle solution à l'avenir.
la source
bla.exe aAAA"b\"ASDS\"c"dSADSD
que les résultats de laaAAAb"ASDS"cdSADSD
sortie de cette solutionaAAA"b"ASDS"c"dSADSD
. Je pourrais envisager de changer leTrimMatchingQuotes
en aRegex("(?<!\\\\)\\\"")
et l'utiliser comme ça .Environment.GetCommandLineArgs ()
la source
J'aime les itérateurs, et de nos jours, LINQ rend
IEnumerable<String>
aussi facilement utilisable que des tableaux de chaînes, donc mon point de vue suivant l'esprit de la réponse de Jeffrey L Whitledge est (en tant que méthode d'extension destring
):la source
Dans votre question, vous avez demandé une expression régulière, et j'en suis un grand fan et utilisateur, alors quand j'ai eu besoin de faire ce même argument partagé que vous, j'ai écrit ma propre expression régulière après avoir cherché sur Google et ne pas trouver une solution simple. J'aime les solutions courtes, alors j'en ai fait une et la voici:
Il gère les espaces et les guillemets entre guillemets et convertit les "" en "inclus. N'hésitez pas à utiliser le code!
la source
Oh diable. C'est tout ... Eugh. Mais c'est officiel légitime. De Microsoft en C # pour .NET Core, peut-être Windows uniquement, peut-être multiplate-forme, mais sous licence MIT.
Sélectionnez des bribes, des déclarations de méthode et des commentaires notables;
-
-
Il s'agit de code porté sur .NET Core à partir de .NET Framework à partir de ce que je suppose être la bibliothèque MSVC C ou
CommandLineToArgvW
.Voici ma tentative sans enthousiasme de gérer certaines des manigances avec des expressions régulières et d'ignorer l'argument zéro bit. C'est un peu sorcier.
Je l'ai testé un peu sur la sortie générée farfelue. Sa sortie correspond à un bon pourcentage de ce que les singes ont tapé et parcouru
CommandLineToArgvW
.la source
Cet article The Code Project est ce que j'ai utilisé dans le passé. C'est un bon morceau de code, mais cela pourrait fonctionner.
Cet article MSDN est la seule chose que j'ai pu trouver qui explique comment C # analyse les arguments de ligne de commande.
la source
Une solution purement gérée peut être utile. Il y a trop de commentaires "problème" pour la fonction WINAPI et elle n'est pas disponible sur d'autres plates-formes. Voici mon code qui a un comportement bien défini (que vous pouvez changer si vous le souhaitez).
Il devrait faire la même chose que ce que fait .NET / Windows lors de la fourniture de ce
string[] args
paramètre, et je l'ai comparé à un certain nombre de valeurs «intéressantes».Il s'agit d'une implémentation de machine à états classique qui prend chaque caractère de la chaîne d'entrée et l'interprète pour l'état actuel, produisant une sortie et un nouvel état. L'état est défini dans les variables
escape
,inQuote
,hadQuote
etprevCh
, et la sortie est recueillie danscurrentArg
etargs
.Certaines des spécialités que j'ai découvertes par des expériences sur une vraie invite de commande (Windows 7):
\\
produit\
,\"
produit"
,""
dans une plage citée produit"
.Le
^
personnage semble aussi magique: il disparaît toujours lorsqu'il ne le double pas. Sinon, cela n'a aucun effet sur une vraie ligne de commande. Mon implémentation ne prend pas en charge cela, car je n'ai pas trouvé de modèle dans ce comportement. Peut-être que quelqu'un en sait plus.Quelque chose qui ne rentre pas dans ce modèle est la commande suivante:
La
cmd
commande semble attraper les guillemets extérieurs et prendre le reste textuellement. Il doit y avoir une sauce magique spéciale là-dedans.Je n'ai fait aucun benchmark sur ma méthode, mais considérez-la raisonnablement rapide. Il n'utilise
Regex
et ne fait aucune concaténation de chaînes mais utilise à la place aStringBuilder
pour collecter les caractères d'un argument et les met dans une liste.la source
Utilisation:
Basé sur la réponse de Vapor in the Alley , celui-ci prend également en charge ^ échappe.
Exemples:
Il prend également en charge plusieurs espaces (casse les arguments une seule fois par bloc d'espaces).
la source
Actuellement, c'est le code que j'ai:
Cela ne fonctionne pas avec les citations échappées, mais cela fonctionne pour les cas auxquels je me suis heurté jusqu'à présent.
la source
Ceci est une réponse au code d'Anton, qui ne fonctionne pas avec des guillemets échappés. J'ai modifié 3 lieux.
la source
Je ne pense pas qu'il existe des guillemets simples ou des guillemets ^ pour les applications C #. La fonction suivante fonctionne bien pour moi:
la source
Vous pouvez consulter le code que j'ai publié hier:
[C #] Chaînes de chemin et d'arguments
Il divise un nom de fichier + des arguments en chaîne []. Les chemins d'accès courts, les variables d'environnement et les extensions de fichier manquantes sont gérés.
(Au départ, c'était pour UninstallString dans le registre.)
la source
Essayez ce code:
C'est écrit en portugais.
la source
posicao_ponteiro += ((fim - posicao_ponteiro)+1);
.Voici une ligne unique qui fait le travail (voir la ligne qui fait tout le travail à l'intérieur de la méthode BurstCmdLineArgs (...)).
Pas ce que j'appellerais la ligne de code la plus lisible, mais vous pouvez la décomposer pour des raisons de lisibilité. C'est volontairement simple et ne fonctionne pas bien pour tous les cas d'argument (comme les arguments de nom de fichier qui contiennent le délimiteur de caractère de chaîne divisée).
Cette solution a bien fonctionné dans mes solutions qui l'utilisent. Comme je l'ai dit, cela fait le travail sans un nid de code pour gérer tous les formats d'argument n-factoriels possibles.
la source
Je n'ai rien trouvé que j'aimais ici. Je déteste gâcher la pile avec de la magie de rendement pour une petite ligne de commande (si c'était un flux d'un téraoctet, ce serait une autre histoire).
Voici mon avis, il prend en charge les échappements de guillemets avec des guillemets doubles comme ceux-ci:
résultat:
la source
J'ai implémenté la machine d'état pour avoir les mêmes résultats d'analyseur que si les arguments étaient passés dans l'application .NET et traités dans la
static void Main(string[] args)
méthode.la source
Voici la solution qui traite les espaces (espaces simples ou multiples) comme séparateur de paramètres de ligne de commande et renvoie les arguments réels de la ligne de commande:
la source
Je ne suis pas sûr de vous avoir compris, mais est-ce que le problème est que le caractère utilisé comme séparateur se trouve également à l'intérieur du texte? (Sauf que c'est échappé avec double "?)
Si tel est le cas, je créerais une
for
boucle et remplacerais toutes les instances où <"> est présent par <|> (ou un autre caractère" sûr ", mais assurez-vous qu'il remplace uniquement <">, et non <"">Après avoir itéré la chaîne, je ferais comme indiqué précédemment, diviser la chaîne, mais maintenant sur le caractère <|>.
la source
Oui, l'objet string a une fonction intégrée appelée
Split()
qui prend un seul paramètre spécifiant le caractère à rechercher comme délimiteur, et renvoie un tableau de chaînes (string []) avec les valeurs individuelles.la source