Perl Regex Extract first two section of windows path - regex

I want to write a method to extract first two sections of windows path in Perl.
For example,
'D:\git_root_tfs\WorkStation\Projects\InterACT\Tools\server-rule-checker'
Extract as:
'D:\git_root_tfs\WorkStation'
sub Split_Location_as_VMPath {
my $location = shift;
# ^([d-z]:\\.+?\\.+?)\\
# ^(?:\\.*\\.*)\\
if($location ~~ m/^(?:\\.*\\.*)\\/){ # the path drive start from D to E;
# print "VMPath=$1\n";
# push #$vmPathList, $1;
return Convert_to_Lowercase($1);
}
return "Invalid Path $location";
}
How to write the regex?
Test case:
{
my $item = Split_Location_as_VMPath('D:\VM\ia7-BGCDev8.1\test.vhd');
my $expected = Convert_to_Lowercase('D:\VM\ia7-BGCDev8.1');
ok( $item eq $expected, "Test Split_Location_as_VMPath=$item");
$item = Split_Location_as_VMPath('E:\Hyper-V-2\ia-int-7.1Beta\test.vhd');
$expected = Convert_to_Lowercase('E:\Hyper-V-2\ia-int-7.1Beta');
ok( $item eq $expected, "Test Split_Location_as_VMPath=$item");
$item = Split_Location_as_VMPath('D:\VM\ia7-int-7.1\test.vhd');
$expected = Convert_to_Lowercase('D:\VM\ia7-int-7.1');
ok( $item eq $expected, "Test Split_Location_as_VMPath=$item");
$item = Split_Location_as_VMPath('D:\VM\ia7-int-8.1B153\test.vhd');
$expected = Convert_to_Lowercase('D:\VM\ia7-int-8.1B153');
ok( $item eq $expected, "Test Split_Location_as_VMPath=$item");
$item = Split_Location_as_VMPath('D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)\test.vhd');
$expected = Convert_to_Lowercase('D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)');
ok( $item eq $expected, "Test Split_Location_as_VMPath=$item");
$item = Split_Location_as_VMPath('D:\git_root_tfs\WorkStation\Projects\InterACT\Tools\server-rule-checker');
$expected = Convert_to_Lowercase('D:\git_root_tfs\WorkStation');
ok( $item eq $expected, "Test Split_Location_as_VMPath=$item");
}

Don't use a regex for file processing.
Instead use a module like File::Spec or Path::Tiny.
use strict;
use warnings;
use File::Spec;
while (<DATA>) {
my ($vol, $dir, $file) = File::Spec->splitpath($_);
my #dirs = File::Spec->splitdir($dir);
#dirs = #dirs[0..2] if #dirs > 3;
$dir = File::Spec->catdir(#dirs);
my $path = File::Spec->catpath($vol, $dir);
print "$path\n";
}
__DATA__
D:\VM\ia7-BGCDev8.1\test.vhd
E:\Hyper-V-2\ia-int-7.1Beta\test.vhd
D:\VM\ia7-int-7.1\test.vhd
D:\VM\ia7-int-8.1B153\test.vhd
D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)\test.vhd
D:\git_root_tfs\WorkStation\Projects\InterACT\Tools\server-rule-checker
Outputs:
D:\VM\ia7-BGCDev8.1
E:\Hyper-V-2\ia-int-7.1Beta
D:\VM\ia7-int-7.1
D:\VM\ia7-int-8.1B153
D:\Hyper-v\IA5-SDE-WIN2K3(Feng Tong)
D:\git_root_tfs\WorkStation

Correct regex is ^([d-z]:\.+?\.+?)\.
sub Split_Location_as_VMPath {
my $location = shift;
# ^([d-z]:\\.+?\\.+?)\\
# ^(?:\\.*\\.*)\\
if($location ~~ m/^([D-Z]:\\.+?\\.+?)\\/){ # the path drive start from D to E;
# print "VMPath=$1\n";
# push #$vmPathList, $1;
return Convert_to_Lowercase($1);
}
return "Invalid Path $location";
}

Using regex in this context is an interesting homework for students. Outside school, you should use the standard modules dedicated for this task:
use File::Spec;
sub Split_Location_as_VMPath {
my $location = shift;
my ($volume, $directories, $file) = File::Spec->splitpath($location);
my #dirs = File::Spec->splitdir($directories);
return "Invalid Path $location" unless #dirs > 2;
return lc File::Spec->catpath($volume, File::Spec->catdir(#dirs[0..2]));
}

Related

powershell System.Collections.Generic.List[System.String] and foreach

I'm finding that I have the following Generic List, and I can see it has items in it, but when I try to run the code, it's not hitting inside the foreach. This is my code:
function SQLQueryWriteToFile([string]$SQLquery, [string]$extractFile)
{
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=blah;Database=blah;User ID=blah;Password=blah" #production #I have an error in this so it doesn't connect
$sqlConnection.Open()
if($sqlConnection.State -ne 'Open'){
$global:ErrorStrings.Add("Exception: $("Couldn't connect to DB with connection string given");; ") #this gets hit
}
###
$global:ErrorStrings = New-Object System.Collections.Generic.List[System.String] #System.Object]
$query = "Select blah"
$dir = "C:\blah"
SQLQueryWriteToFile $query $dir
$errorCodeAsString = ""
foreach ($item in $global:ErrorStrings.Members){
$errorCodeAsString += $item #this isn't hit
}
Any idea why it's not finding the error string in my list for the foreach loop, when I can see it's in there looking at $global:ErrorStrings? Based on this foreach list, I'm doing it correctly. I'm having trouble finding examples like what I'm doing. Thanks!
try this:
function SQLQueryWriteToFile([string]$SQLquery, [string]$extractFile)
{
[System.Data.SqlClient.SqlConnection] $sqlConnection=$null
[System.Data.SqlClient.SqlCommand] $command=$null
try
{
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server=blah;Database=blah;User ID=blah;Password=blah"
$command = New-Object System.Data.SqlClient.SqlCommand
$command.Connection=$sqlConnection
$command.CommandText=$SQLquery
$sqlConnection.Open()
$command.ExecuteNonQuery()
}
catch
{
$global:ErrorStrings.Add($_.Exception.Message)
}
finally
{
if ($sqlConnection -ne $null)
{
$sqlConnection.Close()
$sqlConnection.Dispose()
}
if ($command -ne $null)
{
$command.Dispose()
}
}
}
$global:ErrorStrings = New-Object System.Collections.Generic.List[System.String]
$query = "Select blah"
$dir = "C:\blah"
$global:ErrorStrings.Clear()
SQLQueryWriteToFile $query $dir
$errorCodeAsString=""
for ($i = 0; $i -lt $global:ErrorStrings.Count; $i++)
{
$errorCodeAsString +=$global:ErrorStrings.Item($i)
}
$errorCodeAsString

How to make controller opencart function

I have this script for making subdomain and I want to placed it in the opencart contoller. How to do that and how to make it work with the insert function?
$cpanel_user = 'root';
$cpanel_pass = 'password';
$cpanel_skin = 'x2';
$cpanel_host = 'yourdomain.com';
$subdomain = 'mysubdomain';
$dir = 'public_html/mysubdomain';
$sock = fsockopen($cpanel_host,2082);
if(!$sock) {
print('Socket error');
exit();
}
$pass = base64_encode("$cpanel_user:$cpanel_pass");
$in = "GET /frontend/$cpanel_skin/subdomain/doadddomain.html?rootdomain=$cpanel_host&domain=$subdomain&dir=$dir\r\n";
$in .= "HTTP/1.0\r\n";
$in .= "Host:$cpanel_host\r\n";
$in .= "Authorization: Basic $pass\r\n";
$in .= "\r\n";
fputs($sock, $in);
while (!feof($sock)) {
$result .= fgets ($sock,128);
}
fclose($sock);

perl regular expression to substitute content of a xml tag content

The following tags are in the same format in the file and not well formed
I want to replace the tags inside user tag with name test with my custom text.
xml parser in perl cant be used as it is not pure xml.
<user name="test">
<option name="test2">dev</option>
<option name="test3">csm></option>
</user>
<user name="test12">
<option name="test21">dev1</option>
<option name="test31">csm1></option>
</user>
this is how i managed to do it.
open(FILE,"<","menu1.xml");
open(OUT,">","menu12.xml");
my #values = split('\n', $data);
my $ind = 0;
my $arraysize = #values;
while (($input = <FILE>))
{
print OUT $input;
if($input =~ m/<menu name="">/)
{
while (defined($input = <FILE>) && ($input !~ m/<\/menu>/))
{
print OUT $input;
if ($input =~ m/.+user name="(.*)">/ && $1 eq $access_type)
{
while (defined($input = <FILE>) && ($input !~ m/<\/user>/))
{
if($ind < $arraysize)
{
$input =~ s/<(.*) name="(.*)">(.*)<\/(.*)>/$values[$ind]/;
print OUT $input;
$ind = $ind+1;
}
}
if($input =~ m/<\/user>/)
{
print OUT $input;
}
}
}
if($input =~ m/<\/menu>/)
{
print OUT $input;
}
}
}

Perl Regex for zero or one match

Below are the two strings-
12/31/2011 05:34:27;U;11.comp;host=win workgroup=home username=bob cmemory=1325133456 qmemory=1325133456 smemory=1325133456 uptime=1325289867
12/31/2011 01:09:20;D;12.comp;host=win workgroup=home username=sam cmemory=1325151687 qmemory=1325151687 smemory=1325151687 uptime=1325228636 session=4677 downtime=1325270175 Exit_status=0
From above strings I want to pick host, workgroup, username, uptime and downtime values using Regex in Perl.
Below is my Perl script-
foreach $line (<FILE>) {
if($line =~ m<\d{2}/\d{2}/\d{4}\s+\d{2}:\d{2}:\d{2};[U|D].*host=(\w+)\s+workgroup=(\w+)\s+hostname=(\w+)\s+.*uptime=(\d+)\s+.*(downtime=)?(\d*)>){
my $host = $1;
my $workgroup = $2;
my $hostname = $3;
my $uptime = $4;
my $downtime = $5;
print "host=$host workgroup=$workgroup hostname=$hostname uptime=$uptime downtime=$downtime\n";
}
}
The only problem, I am facing here is because of downtime. This attribute may not be present in the line. I am not able to pick this field properly.
Why not use split instead? Then you could add the various categories to a hash, like so:
use strict;
use warnings;
use Data::Dumper;
while (<DATA>) {
my ($date, $foo, $bar, $data) = split /;/, $_, 4;
my %data = map { split /=/ } split ' ', $data;
print Dumper \%data;
}
__DATA__
12/31/2011 05:34:27;U;11.comp;host=win workgroup=home username=bob cmemory=1325133456 qmemory=1325133456 smemory=1325133456 uptime=1325289867
12/31/2011 01:09:20;D;12.comp;host=win workgroup=home username=sam cmemory=1325151687 qmemory=1325151687 smemory=1325151687 uptime=1325228636 session=4677 downtime=1325270175 Exit_status=0
Output:
$VAR1 = {
'workgroup' => 'home',
'cmemory' => '1325133456',
'qmemory' => '1325133456',
'uptime' => '1325289867',
'smemory' => '1325133456',
'username' => 'bob',
'host' => 'win'
};
$VAR1 = {
'qmemory' => '1325151687',
'Exit_status' => '0',
'smemory' => '1325151687',
'username' => 'sam',
'host' => 'win',
'workgroup' => 'home',
'cmemory' => '1325151687',
'session' => '4677',
'downtime' => '1325270175',
'uptime' => '1325228636'
};
If you now want to refer to the "downtime" value, you can do something such as:
my $downtime = $hash{downtime} // "N/A";
Where // is the defined-or operator, somewhat preferred here over logical or ||.

How to search a substring in PHP array using regExp

$array = array(
array('foo_test1','demo_test1'),
array('foo_test2','demo_test2'),
array('blah_test1','exp_test1'),
array('blah_test2','exp_test2'),
array('foo_test3','demo_test3')
)
How to get all subarray which contains foo substring with its value using php and regExp.
Expected Output:
$array = array(
array('foo_test1','demo_test1'),
array('foo_test2','demo_test2'),
array('foo_test3','demo_test3')
)
You should be able to do it with
preg_grep($pattern,$array)
$input = array( /* your array */ );
$output = array();
foreach ( $input as $data ) {
$len = length($data);
for ( $i = 0; $i < $len; ++$i ) {
if ( strpos($data[$i], 'foo') > -1 ) {
$output[] = $data;
break;
}
}
}
$array = array(
array('foo_test1','demo_test1'),
array('foo_test2','demo_test2'),
array('blah_test1','exp_test1'),
array('blah_test2','exp_test2'),
array('foo_test3','demo_test3')
);
$search = 'foo';
$res = array();
foreach ($array as $arr) {
foreach ($arr as $value) {
if (preg_match('~'.preg_quote($search,'~').'~',$value)) {
// if one of the values in that array
// has the search word in it...
$res[] = $arr; break;
// push it into the $res and break
// the inner foreach loop
}
}
}
print_r($res);