I'm trying to remove the username in a string. Tried the code below but it removes everything after the #
$string = 'he #username die';
$string = preg_replace('/#.*/','',$string);
echo $string; // output: he
I want the output to be: he die
Thanks
Use \S that means anything that is not a space character (the opposite of \s) instead of .:
$string = 'he #username die';
$string = preg_replace('/#\S+/','',$string);
echo $string; // output: he die
You may want to remove also the following space:
$string = 'he #username die';
$string = preg_replace('/#\S+\s*/','',$string);
echo $string; // output: he die
Related
I'm embarrassed to ask this because it is so simple, but I can't see what's wrong. I have a routine to clean up input for an ip range. It's sort of brute-force but I don't know of a better way. The problem I am having is when I try to remove inner spaces leaving only a '-' or ',' as separators within a conditional block a single preceding and trailing space is left bracketing the separator. If I clean up the inner spaces outside the conditional block the spaces are properly removed. So, in the sample code if I only have the s/\s+//g on Line 1 it cleans properly, if I only have the s/\s+//g on Lines 2 and 3 spaces are left bracketing the '-' and ','. What the heck is wrong?
use feature qw(say);
use Data::Dumper qw(Dumper);
$input = " 192.168.1.1 198.168.1.254 ";
buildIpRangeArray ($input);
$input = " 192.168.1.1 , 198.168.1.254 ";
buildIpRangeArray ($input);
$input = " 192.168.1.1 - 198.168.1.254 ";
buildIpRangeArray ($input);
sub buildIpRangeArray {
say "input: $input";
$input = shift;
$input =~ s/^\s+//;
$input =~ s/\s+$//;
# $input =~ s/\s+//g; # Line 1.
# Works if this is uncommented
# and lines 2 and 3 are omitted
if ( index($input,' ') >= 0) {
$input =~ s/\s+/ /g; # this works
say "cleaned input 2: $input";
#range = split(/ /,$input);
say Dumper(#range);
}
elsif ( index($input,',') >= 0) {
$input =~ s/\s+//g; # Line 2
say "cleaned input 3: $input";
#range = split(/,/, $input);
say Dumper(#range);
}
elsif ( index($input,'-') >= 0) {
$input =~ s/\s+//g; # Line 3
say "cleaned input 4: $input";
#range = split(/-/, $input);
say Dumper(#range);
}
}
The output:
input: 192.168.1.1 198.168.1.254
cleaned input 2: 192.168.1.1 198.168.1.254
$VAR1 = '192.168.1.1';
$VAR2 = '198.168.1.254';
input: 192.168.1.1 , 198.168.1.254
cleaned input 2: 192.168.1.1 , 198.168.1.254
$VAR1 = '192.168.1.1';
$VAR2 = ',';
$VAR3 = '198.168.1.254';
input: 192.168.1.1 - 198.168.1.254
cleaned input 2: 192.168.1.1 - 198.168.1.254
$VAR1 = '192.168.1.1';
$VAR2 = '-';
$VAR3 = '198.168.1.254';
If you look at your debug output, it's fairly obvious what's going on. Let's take the second block of output with the comma.
input: 192.168.1.1 , 198.168.1.254
cleaned input 2: 192.168.1.1 , 198.168.1.254
$VAR1 = '192.168.1.1';
$VAR2 = ',';
$VAR3 = '198.168.1.254';
After input, there is a check to see if there's a space ' ' in the string. There is, here:
V
192.168.1.1 , 198.168.1.254
Therefore the code never reaches the elsif for the comma , or the dash -. You can verify that because you always get input 2, never input 3 or input 4.
The next step is cleaning whitespace, where you say yourself it works. You replace lots of any whitespace with one space. That leaves , in the string. Now you split on whitespace, giving you
ip
,
ip
Overall, your code is fairly naive. There is a lot of repetition, and you don't have use strict or use warnings, which makes it harder to debug. Depending on how this code is going to be used, I suggest a huge simplification.
sub buildIpRangeArray {
my $input = shift;
say "input: $input";
my #range = grep {$_} split /[^0-9.]+/, $input;
say Dumper #range;
return;
}
We split on lots of characters that can't be in an IP address. This is naive too, as it will not verify you have actual IP addresses, but neither does your code. It will work for any number of whitespace or any delimiters, even if they are text. We need the grep to remove empty strings that occur from leading or trailing whitespace. An empty string "" in Perl evaluates as false, so grep will filter these out.
Your first condition is always true, as the string always contains spaces.
So you have to write the if/elsif/elsif in another way.
if ( index($input,',') >= 0) {
$input =~ s/\s+//g; # Line 2
say "cleaned input 3: $input";
#range = split(/,/, $input);
say Dumper(#range);
}
elsif ( index($input,'-') >= 0) {
$input =~ s/\s+//g; # Line 3
say "cleaned input 4: $input";
#range = split(/-/, $input);
say Dumper(#range);
}
elsif ( index($input,' ') >= 0) {
$input =~ s/\s+/ /g; # this works
say "cleaned input 2: $input";
#range = split(/ /,$input);
say Dumper(#range);
}
will probably yield the result you want.
I would like to know how to append to a text file using Perl in this condition.
I have a text file, the content of it is:
apple,123,456,orange
cat,789,lion
I have a variable in a loop like this
for 1st loop:
my $text1 = "hi"
my $text2 = "go"
for 2nd loop:
my $text1 = "banana"
my $text2 = "car"
I would like to have the result in the text file
apple,123,456,orange,hi,banana
cat,789,lion,go,car
How can I do this?
You haven't described your problem very well and seem to be ignoring the requests for additional information. However, here's a program that matches your description and may help you
use strict;
use warnings;
my #extra = (
[qw/ hi go /],
[qw/ banana car /],
);
my #data = <DATA>;
chomp #data;
for ( #extra ) {
my ($text1, $text2) = #$_;
$data[0] .= ",$text1";
$data[1] .= ",$text2";
}
print "$_\n" for #data;
__DATA__
apple,123,456,orange
cat,789,lion
output
apple,123,456,orange,hi,banana
cat,789,lion,go,car
I want my program to divide the string by the spaces between them
$string = "hello how are you";
The output should look like that:
hello
how
are
you
You can do this is a few different ways.
use strict;
use warnings;
my $string = "hello how are you";
my #first = $string =~ /\S+/g; # regex capture non-whitespace
my #second = split ' ', $string; # split on whitespace
my $third = $string;
$third =~ tr/ /\n/; # copy string, substitute space for newline
# $third =~ s/ /\n/g; # same thing, but with s///
The first two creates arrays with the individual words, the last creates a different single string. If all you want is something to print, the last will suffice. To print an array do something like:
print "$_\n" for #first;
Notes:
Normally, regex capture requires parentheses /(\S+)/, but when the /g modifier is used, and parentheses are omitted, the entire match is returned.
When using capture this way, you need to assure list context on the assignment. If the left hand parameter is a scalar, you would force list context with parentheses: my ($var) = ...
I think like simple....
$string = "hello how are you";
print $_, "\n" for split ' ', $string;
#Array = split(" ",$string); then the #Array contain the answer
You need a split for dividing the string by spaces like
use strict;
my $string = "hello how are you";
my #substr = split(' ', $string); # split the string by space
{
local $, = "\n"; # setting the output field operator for printing the values in each line
print #substr;
}
Output:
hello
how
are
you
Split with regexp to account for extra spaces if any:
my $string = "hello how are you";
my #words = split /\s+/, $string; ## account for extra spaces if any
print join "\n", #words
I need to remove every \r \n and \ in that order from a big $string, how can I accomplish that?
Example string:
$string = '\/9jAAMAAAAB\r\nAAEAAABAAAD\/2'
need it to look like this:
$string = '/9jAAMAAAABAAEAAABAAAD/2'
#!/usr/bin/perl
$string = "something\\r\\n\\";
$string =~ s/(\\r)|(\\n)|(\\)//g;
print $string;
=> something
Here's another option:
use strict;
use warnings;
my $string = '\/9jAAMAAAAB\r\nAAEAAABAAAD\/2';
$string =~ s!\\[rn]?!!g;
print $string;
Output:
/9jAAMAAAABAAEAAABAAAD/2
Here is one way to do it:
$new_string = $string =~ s/\\|\R//g;
print "$new_string";
Can you assist me in determing correct $string = line to end up with partial_phone containing 4165867111?
sub phoneno {
my ($string) = #_;
$string =~ s/^\+*0*1*//g;
return $string;
}
my $phone = "<sip:+4165867111#something;tag=somethingelse>";
my $partial_phone = phoneno($phone);
$string =~ s{
\A # beginning of string
.+ # any characters
\+ # literal +
( # begin capture to $1
\d{5,} # at least five digits
) # end capture to $`
\# # literal #
.+ # any characters
\z # end of string
}{$1}xms;
Your substitution starts with a ^, which means it won't perform substitution unless the rest of your pattern matches the start of your string.
There are lots of ways to do this. How about
my ($partial) = $phone =~ /([2-9]\d+)/;
return $partial;
This returns any string of digits that doesn't begin with a 0 or 1.
This will capture all digits preceding the #:
use strict;
use warnings;
sub phoneno {
my ($string) = #_;
my ($phoneNo) = $string =~ /(\d+)\#/;
return $phoneNo;
}
my $phone = '<sip:+4165867111#something;tag=somethingelse>';
my $partial_phone = phoneno($phone);
print $partial_phone;
Output:
4165867111