I have to extract a string from square brackets using Powershell or Groovy script.
PowerShell :
$string = "[test][OB-110] this is some text"
$found = $string -match '(?<=\[)[^]]+(?=\])'
echo $matches
When I run the above code it returns :
test
I want it to return this :
test
OB-110
I need to extract all text within brackets.
-match will internally call Regex.Match() in the background, which in turn will only capture the first match.
Either use Select-String with the -AllMatches switch:
($string |Select-String '(?<=\[)[^]]+(?=\])' -AllMatches).Matches.Value
Or invoke Regex.Matches() directly:
[regex]::Matches($string, '(?<=\[)[^]]+(?=\])').Value
For Groovy:
def str = "[test][OB-110] this is some text"
str.findAll(/(?<=\[)[^]]+(?=\])/).each {
println it
}
Which prints
test
OB-110
Related
I'm trying to replace part of a string in Powershell. However, the replacement string is not hardcoded, it's calculated from a function:
$text = "the image is -12345-"
$text = $text -replace "-(\d*)-", 'This is the image: $1'
Write-Host $text
This gives me the correct result:
"This is the image: 12345"
Now, I want to include the base64 encoded image. I can read the image from the id. I was hoping the following would work, but it doesn't:
function Get-Base64($path)
{
[convert]::ToBase64String((get-content $path -encoding byte))
}
$text -replace "-(\d*)-", "This is the image: $(Get-Base64 '$1')"
The reason that it doesn't work, is because it first passes $1 (the string, not the value of $1) to the function, executes it and only then does it do the replace. What I want to do is
Find the occurrence of the pattern
Replace each occurence with the pattern
For each replace:
Pass the capture group to the function
Use the value of the capture group to get the base64 image
inject the base64 image into the replacement
You can use the static Replace method from the [regex] class:
[regex]::Replace($text,'-(\d*)-',{param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})
Alternatively you can define a regex object and use the Replace method of that object:
$re = [regex]'-(\d*)-'
$re.Replace($text, {param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})
For better readability you could define the callback function (the scriptblock) in a separate variable and use that in the replacement:
$callback = {
param($match)
'This is the image: ' + (Get-Base64 $match.Groups[1].Value)
}
$re = [regex]'-(\d*)-'
$re.Replace($text, $callback)
PetSerAl's helpful answer is your only option in Windows PowerShell, as of v5.1.
PowerShell Core v6.1+ now offers a native PowerShell solution via an enhancement to the
-replace operator, which obviates the need to call [regex]::Replace():
Just as with [regex]::Replace(), you can now:
pass a script block as the -replace replacement operand, which must return the replacement string,
except that the match at hand (an instance of type [System.Text.RegularExpressions.Match]) is represented as automatic variable $_, as is customary in PowerShell.
Applied to your case:
$text -replace "-(\d*)-", { "This is the image: $(Get-Base64 $_.Groups[1].Value)" }
A simpler example:
# Increment the number embedded in a string:
PS> '42 years old' -replace '\d+', { [int] $_.Value + 1 }
43 years old
Here's another way. Use the -match operator, and then reference $matches. Note that $matches doesn't get set with arrays on the left side of the -match operator. $matches.1 is the first grouping formed by the ( ).
$text = "the image is -12345-"
function Get-Base64($path) {
[convert]::ToBase64String( (get-content $path -asbytestream) ) } # ps 6 ver
if (! (test-path 12345)) { echo hi > 12345 }
$text -match '-(\d*)-'
$text -replace '-(\d*)-', "$(Get-Base64 $matches.1)"
the image is aGkNCg==
Or to break it up even more:
$text -match '-(\d*)-'
$result = Get-Base64 $matches.1
$text -replace '-(\d*)-', $result
I'm trying to replace part of a string in Powershell. However, the replacement string is not hardcoded, it's calculated from a function:
$text = "the image is -12345-"
$text = $text -replace "-(\d*)-", 'This is the image: $1'
Write-Host $text
This gives me the correct result:
"This is the image: 12345"
Now, I want to include the base64 encoded image. I can read the image from the id. I was hoping the following would work, but it doesn't:
function Get-Base64($path)
{
[convert]::ToBase64String((get-content $path -encoding byte))
}
$text -replace "-(\d*)-", "This is the image: $(Get-Base64 '$1')"
The reason that it doesn't work, is because it first passes $1 (the string, not the value of $1) to the function, executes it and only then does it do the replace. What I want to do is
Find the occurrence of the pattern
Replace each occurence with the pattern
For each replace:
Pass the capture group to the function
Use the value of the capture group to get the base64 image
inject the base64 image into the replacement
You can use the static Replace method from the [regex] class:
[regex]::Replace($text,'-(\d*)-',{param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})
Alternatively you can define a regex object and use the Replace method of that object:
$re = [regex]'-(\d*)-'
$re.Replace($text, {param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})
For better readability you could define the callback function (the scriptblock) in a separate variable and use that in the replacement:
$callback = {
param($match)
'This is the image: ' + (Get-Base64 $match.Groups[1].Value)
}
$re = [regex]'-(\d*)-'
$re.Replace($text, $callback)
PetSerAl's helpful answer is your only option in Windows PowerShell, as of v5.1.
PowerShell Core v6.1+ now offers a native PowerShell solution via an enhancement to the
-replace operator, which obviates the need to call [regex]::Replace():
Just as with [regex]::Replace(), you can now:
pass a script block as the -replace replacement operand, which must return the replacement string,
except that the match at hand (an instance of type [System.Text.RegularExpressions.Match]) is represented as automatic variable $_, as is customary in PowerShell.
Applied to your case:
$text -replace "-(\d*)-", { "This is the image: $(Get-Base64 $_.Groups[1].Value)" }
A simpler example:
# Increment the number embedded in a string:
PS> '42 years old' -replace '\d+', { [int] $_.Value + 1 }
43 years old
Here's another way. Use the -match operator, and then reference $matches. Note that $matches doesn't get set with arrays on the left side of the -match operator. $matches.1 is the first grouping formed by the ( ).
$text = "the image is -12345-"
function Get-Base64($path) {
[convert]::ToBase64String( (get-content $path -asbytestream) ) } # ps 6 ver
if (! (test-path 12345)) { echo hi > 12345 }
$text -match '-(\d*)-'
$text -replace '-(\d*)-', "$(Get-Base64 $matches.1)"
the image is aGkNCg==
Or to break it up even more:
$text -match '-(\d*)-'
$result = Get-Base64 $matches.1
$text -replace '-(\d*)-', $result
I'm trying to replace part of a string in Powershell. However, the replacement string is not hardcoded, it's calculated from a function:
$text = "the image is -12345-"
$text = $text -replace "-(\d*)-", 'This is the image: $1'
Write-Host $text
This gives me the correct result:
"This is the image: 12345"
Now, I want to include the base64 encoded image. I can read the image from the id. I was hoping the following would work, but it doesn't:
function Get-Base64($path)
{
[convert]::ToBase64String((get-content $path -encoding byte))
}
$text -replace "-(\d*)-", "This is the image: $(Get-Base64 '$1')"
The reason that it doesn't work, is because it first passes $1 (the string, not the value of $1) to the function, executes it and only then does it do the replace. What I want to do is
Find the occurrence of the pattern
Replace each occurence with the pattern
For each replace:
Pass the capture group to the function
Use the value of the capture group to get the base64 image
inject the base64 image into the replacement
You can use the static Replace method from the [regex] class:
[regex]::Replace($text,'-(\d*)-',{param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})
Alternatively you can define a regex object and use the Replace method of that object:
$re = [regex]'-(\d*)-'
$re.Replace($text, {param($match) "This is the image: $(Get-Base64 $match.Groups[1].Value)"})
For better readability you could define the callback function (the scriptblock) in a separate variable and use that in the replacement:
$callback = {
param($match)
'This is the image: ' + (Get-Base64 $match.Groups[1].Value)
}
$re = [regex]'-(\d*)-'
$re.Replace($text, $callback)
PetSerAl's helpful answer is your only option in Windows PowerShell, as of v5.1.
PowerShell Core v6.1+ now offers a native PowerShell solution via an enhancement to the
-replace operator, which obviates the need to call [regex]::Replace():
Just as with [regex]::Replace(), you can now:
pass a script block as the -replace replacement operand, which must return the replacement string,
except that the match at hand (an instance of type [System.Text.RegularExpressions.Match]) is represented as automatic variable $_, as is customary in PowerShell.
Applied to your case:
$text -replace "-(\d*)-", { "This is the image: $(Get-Base64 $_.Groups[1].Value)" }
A simpler example:
# Increment the number embedded in a string:
PS> '42 years old' -replace '\d+', { [int] $_.Value + 1 }
43 years old
Here's another way. Use the -match operator, and then reference $matches. Note that $matches doesn't get set with arrays on the left side of the -match operator. $matches.1 is the first grouping formed by the ( ).
$text = "the image is -12345-"
function Get-Base64($path) {
[convert]::ToBase64String( (get-content $path -asbytestream) ) } # ps 6 ver
if (! (test-path 12345)) { echo hi > 12345 }
$text -match '-(\d*)-'
$text -replace '-(\d*)-', "$(Get-Base64 $matches.1)"
the image is aGkNCg==
Or to break it up even more:
$text -match '-(\d*)-'
$result = Get-Base64 $matches.1
$text -replace '-(\d*)-', $result
I am using regular expression to find strings in Powershell, and match function returns empty string lines as well as matched lines.
For the following four lines of text file input.txt,
[abc]
abc
[123]
123
The code below prints out abc/blank line/123/blank line. I expected it only prints out abc and 123, wonder how this happened.
$readArray = Get-Content(input.txt)
foreach($line in $readArray) {
$re = [regex] *** // Find the string in bracket
$key = $re.match($line)
if($key -ne $null) {
write-host -$key.group[1].value
}
}
You can use this regex to get the content within tags:
\[(.*?)\]
Working demo
Try this (use select-string) -
Get-Content -FilePath input.txt |
Select-String '\[(.+?)\]') | ForEach-Object {$_.Matches[0].Groups[1].Value}
I am looking for a solution to do this in Perl.
Example:
If my string is:
my $content = 'toto /app/blah titi\nhuh/app/ttt wew';
and my pattern is: /app/something I want to get as output in an array: /app/blah and /app/ttt.
(which is basically what grep -E -o '\/app\/[a-z]*' does)
I can't get it work !
I tried:
my $content = 'toto /app/blah titi\nhuh/app/ttt wew';
$content =~ m/(\/app\/[a-z]*)/;
print "Group: $1 $2\n";
but this only prints: /app/blah (not /app/ttt)
and anyway, I don't know how to put the results in a table:
my (#table) = #_;
the table does not contain anything!
thx
You want to use the /g modifier to make the regular expression return all the matches as a list:
#table = $content =~ m/(\/app\/[a-z]*)/g;
print "Group: #table\n";
Also, #_ does not have anything to do with regular expressions. Rather, it is the list of parameters that was passed to the current subroutine.
I was working on a one liner for some quick bash scripting where Perl would play one part, this worked for me:
$ echo foo000bar000baz | perl -ne 'for(m/(foo)|(baz)/g){ if ($_ ne "") { print "$_\n"}}'
foo
baz
Works with multiline too
$ echo 'foo
> 123
> bar
> 456
> baz ' | perl -ne 'for(m/(foo)|(baz)/g){ if ($_ ne "") { print "$_\n"}}'
foo
baz
Explanation (Forgive and correct my mistakes as I'm not advanced level at Perl):
STDIN piped to perl : Could be anything, like cat $file
m/Regular Expression within parenthesis indicating capture group/g
Make for loop from matches above
Print if match is not "" (empty)