web-dev-qa-db-fra.com

Extraire une sous-chaîne à l'aide de PowerShell

Comment puis-je extraire une sous-chaîne à l'aide de PowerShell?

J'ai cette ficelle ...

"-----start-------Hello World------end-------"

Je dois extraire ...

Hello World

Quelle est la meilleure façon de le faire?

39
achi

L'opérateur -match teste une expression rationnelle, combinez-le avec la variable magique $matches pour obtenir votre résultat.

PS C:\> $x = "----start----Hello World----end----"
PS C:\> $x -match "----start----(?<content>.*)----end----"
True
PS C:\> $matches['content']
Hello World

En cas de doute sur les choses de regex-y, consultez ce site: http://www.regular-expressions.info

39
Matt Woodard

La méthode Substring nous fournit un moyen d'extraire une chaîne particulière de la chaîne d'origine en fonction de la position et de la longueur de départ. Si un seul argument est fourni, il est considéré comme la position de départ et le reste de la chaîne est sorti.

PS > "test_string".Substring(0,4)
Test
PS > "test_string".Substring(4)
_stringPS >

texte du lien

Mais c'est plus facile ...

 $s = 'Hello World is in here Hello World!'
 $p = 'Hello World'
 $s -match $p

Et enfin, pour recurse dans un répertoire sélectionnant uniquement les fichiers .txt et recherchant l'occurrence de "Hello World":

dir -rec -filter *.txt | Select-String 'Hello World'
33
nineowls

Vous ne savez pas si cela est efficace ou non, mais vous pouvez faire référence à des chaînes dans PowerShell à l'aide de la syntaxe d'index de tableau, de la même manière que Python.

Ce n'est pas complètement intuitif car la première lettre est désignée par index = 0, mais elle le fait:

  • Autoriser un deuxième numéro d'index plus long que la chaîne, sans générer d'erreur
  • Extraire les sous-chaînes en sens inverse
  • Extraire les sous-chaînes de la fin de la chaîne

Voici quelques exemples:

PS > 'Hello World'[0..2]

Donne le résultat (valeurs d'index incluses pour plus de clarté - non générées dans la sortie):

H [0]
e [1]
l [2]

Ce qui peut être rendu plus utile en passant -join '':

PS > 'Hello World'[0..2] -join ''
Hel

Il existe des effets intéressants que vous pouvez obtenir en utilisant différents indices:

En avant

Utilisez une première valeur d'index inférieure à la seconde et la sous-chaîne sera extraite dans le sens suivant comme vous le souhaitiez. Cette fois, la deuxième valeur d'index dépasse de loin la longueur de la chaîne, mais il n'y a pas d'erreur:

PS > 'Hello World'[3..300] -join ''
lo World

Contrairement à:

PS > 'Hello World'.Substring(3,300)
Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within
the string.

En arrière

Si vous fournissez une deuxième valeur d'index inférieure à la première, la chaîne est renvoyée en sens inverse:

PS > 'Hello World'[4..0] -join ''
olleH

De fin

Si vous utilisez des nombres négatifs, vous pouvez vous référer à la position à partir de la fin de la chaîne. Pour extraire 'World', les 5 dernières lettres, nous utilisons:

PS > 'Hello World'[-5..-1] -join ''
World
10
mjsqu
PS> $a = "-----start-------Hello World------end-------"
PS> $a.substring(17, 11)
         or
PS> $a.Substring($a.IndexOf('H'), 11)

$a.Substring(argument1, argument2)-> Here argument1 = Position de départ de l'alphabet souhaité et argument2 = Longueur de la sous-chaîne à afficher en sortie. 

Ici 17 est l’index de l’alphabet 'H' et puisque nous voulons imprimer jusqu’à Hello World, nous fournissons 11 comme deuxième argument.

4
Vivek Kumar Singh

En vous appuyant sur la réponse de Matt, voici une solution qui permet de rechercher parmi de nouvelles lignes et qui est facile à modifier pour votre propre usage

$String="----start----`nHello World`n----end----"
$SearchStart="----start----`n" #Will not be included in results
$SearchEnd="`n----end----" #Will not be included in results
$String -match "(?s)$SearchStart(?<content>.*)$SearchEnd"
$result=$matches['content']
$result

-

REMARQUE: si vous souhaitez l'exécuter sur un fichier, gardez à l'esprit que Get-Content renvoie un tableau et non une chaîne. Vous pouvez contourner ce problème en procédant comme suit:

$String=[string]::join("`n", (Get-Content $Filename))
3
Chris Rudd

autre solution

$template="-----start-------{Value:This is a test 123}------end-------"
$text="-----start-------Hello World------end-------"

$text | ConvertFrom-String -TemplateContent $template
3
Esperento57

J'avais besoin d'extraire quelques lignes dans un fichier journal et cet article m'a aidé à résoudre mon problème. J'ai donc pensé à l'ajouter ici. Si quelqu'un doit extraire plusieurs lignes, vous pouvez utiliser le script pour obtenir l'index d'un mot correspondant à cette chaîne (je cherche "racine") et extraire le contenu dans toutes les lignes.

$File_content = Get-Content "Path of the text file"
$result = @()

foreach ($val in $File_content){
    $Index_No = $val.IndexOf("Root")
    $result += $val.substring($Index_No)
}

$result | Select-Object -Unique

À votre santé..!

0
pause-ee-tive