I have the following string ./test
and I want to replace it with test
so, I wrote the following in perl:
my $t =~ s/^.//;
however, that replaces ./test with /test
can anyone please suggest how I fix it so I get rid of the / too. thanks!
my $t =~ s/^\.\///;
You need to escape the dot and the slash.
The substitution is s/match/replace/. If you erase, it's s/match//. You want to match "starts with a dot and a slash", and that's ^\.\/.
The dot doesn't do what you expect - rather than matching a dot character, it matches any character because of its special treatment. To match a dot and a forward slash, you can rewrite your expression as follows:
my $t =~ s|^\./||;
Note that you are free to use a different character as a delimiter, in order not to confuse it with any such characters inside the regular expression.
If you want to get rid of ./ then you need to include both of those characters in the regex.
s/^\.\///;
Both . and / have special meanings in this expression (. is a regex metacharacter meaning "any character" and / is the delimiter for the s/// operator) so we need to escape them both by putting a \ in front of them.
An alternative (and, in my opinion, better) approach to the / issue is to change the character that you are using as the s/// delimiter.
s|^\./||;
This is all documented in perldoc perlop.
You have to use a backward slash before the dot and the forward slash: s/\.\//;
The backslash is used to write symbols that otherwise would have a different meaning in the regular expression.
You need to write my $t =~ s/^\.\///; (Note that the period needs to be escaped in order to match a literal period rather than any character). If that's too many slashes, you can also change the delimiter, writing instead, e.g., my $t =~ s:^\./::;.
$t=q(./test);$t=~s{^\./}{};print $t;
You need to escape the dot if you want it to match a dot. Otherwise it matches any character. You can choose alternate delimiters --- best when dealing with forward slashes lest you get the leaning-toothpick look when you otherwise need to escape those too.
Note that the dot in your question is matching any character, not a literal '.'.
my $t = './test';
$t =~ s{\./}{};
use Path::Class qw( file );
say file("./test")->cleanup();
Path::Class
Related
For instance, if I wanted to a find and replace with strings containing backward or forward slashes, how would this be accomplished in vim?
Examples
Find & Replace is: :%s/foo/bar/g
what if I wanted to find all occurrences of <dog/> and replace it with <cat\>
Same way you escape characters most anywhere else in linuxy programs, with a backslash:
:%s/<dog\/>/<cat\\>
But note that you can select a different delimiter instead:
:%s#<doc/>#<cat\\>#
This saves you all typing all those time-consuming, confusing backslashes in patterns with a ton of slashes.
From the documentation:
Instead of the / which surrounds the pattern and replacement string, you
can use any other single-byte character, but not an alphanumeric character,
\, " or |. This is useful if you want to include a / in the search
pattern or replacement string.
%s:<dog/>:<cat>
You can replace the / delimiters if they become annoying for certain patterns.
Quote them with a backslash. Also, it often helps to use another delimiter besides slash.
:%s#<dog/>#<cat\\>#
or if you have to use slash as the substitute command delimiter
:%s/<dog\/>/<cat\\>/
I was looking for something similar, to search for register values containing the / character (to record a macro). The solution was to search using the ? token instead of the /.
The syntax is:
:%s/<dog\/>/<cat\\>/g
backslash slash backslash star
/(<- the prompt)\/\*
so after you type it looks like
/\/\*
I have folders in a directory with names giving specific information. For example:
[allied]_remarkable_points_[treatment]
[nexus]_advisory_plans_[inspection]
....
So I have a structure similar to this: [company]_title_[topic]. The script has to match the file naming structure to variables in a script in order to extract the information:
COMPANY='[allied]';
TITLE='remarkable points'
TOPIC='[treatment]'
The folders do not contain a constant number of characters, so I can't use indexed matching in the script. I managed to extract $TITLE and $TOPIC, but I can't manage to match the first string since the variable brings me back the complete folders name.
FOLDERNAME=${PWD##*/}
This is the line is giving me grief:
COMPANY=`expr $FOLDERNAME : '\(\[.*\]\)'`
I tried to avoid the greedy behaviour by placing ? in the regular expression:
COMPANY=`expr $FOLDERNAME : '\(\[.*?\]\)'`
but as soon as I do that, it returns nothing
Any ideas?
expr isn't needed for regular-expression matching in bash.
[[ $FOLDERNAME =~ (\[[^]]*\]) ]] && COMPANY=${BASH_REMATCH[1]}
Use [^]]* instead of .* to do a non-greedy match of the bracketed portion. An bigger regular expression can capture all three parts:
[[ $FOLDERNAME =~ (\[[^]]*\])_([^_]*)_(\[[^]]*\]) ]] && {
COMPANY=${BASH_REMATCH[1]}
TITLE=${BASH_REMATCH[2]}
TOPIC=${BASH_REMATCH[3]}
}
Bash has built-in string manipulation functionality.
for f in *; do
company=${f%%\]*}
company=${company#\[} # strip off leading [
topic=${f##\[}
topic=${f%\]} # strip off trailing ]
:
done
The construct ${variable#wildcard} removes any prefix matching wildcard from the value of variable and returns the resulting string. Doubling the # obtains the longest possible wildcard match instead of the shortest. Using % selects suffix instead of prefix substitution.
If for some reason you do want to use expr, the reason your non-greedy regex attempt doesn't work is that this syntax is significantly newer than anything related to expr. In fact, if you are using Bash, you should probably not be using expr at all, as Bash provides superior built-in features for every use case where expr made sense, once in the distant past when the sh shell did not have built-in regex matching and arithmetic.
Fortunately, though, it's not hard to get non-greedy matching in this isolated case. Just change the regex to not match on square brackets.
COMPANY=`expr "$FOLDERNAME" : '\(\[[^][]*\]\)'`
(The closing square bracket needs to come first within the negated character class; in any other position, a closing square bracket closes the character class. Many newbies expect to be able to use backslash escapes for this, but that's not how it works. Notice also the addition of double quotes around the variable.)
If you're not adverse to using grep, then:
COMPANY=$(grep -Po "^\[.*?\]" $FOLDERNAME)
I am looking through a script that a former employee wrote, and came across this. I am very confused as to what it means. It is a condition of an if loop that runs through a file, and I know what the $rr variable is but everything after that I have no idea what it means... obviously googling "\d" returns nothing pertinent... what is the ".+>" mean too?
if ($line =~ m/($rr)(.+>)(\d.\d+)</) {
I have used the x modifier to make the pattern descriptive:
$line =~ m/
( $rr ) # Match and capture the value of $rr
( .+ > ) # Match and capture everything till the last >
( # Capture the following matches
\d # Match a single digit
. # Match any character a single time
\d+ # Match one or more digits
)
/x;
There are three captures in the above pattern. These captures can be accessed using the special variables $1, $2 and $3.
References
Perl regular expressions tutorial
Perl regular expressions
This is about regular expressions.
if ($line =~ m/($rr)(.+>)(\d.\d+)
$line is a variable.
The =~ means does it match this pattern?
The pattern follows. It's something like m/ then the variable $rr, then . (a single character), + (matches previous character multiple times). The > I'm not sure. The \d means a digit (i.e. 0 through 9).
Reads up on pattern matching and regular expressions here: http://en.wikipedia.org/wiki/Regular_expression
Regular expressions are similar in many languages such as Perl, Ruby, etc.
Check out most of your string here (ruby): http://rubular.com/r/OTe4jFN545
If line matches the regular expression starting with $rr variable followed by atleast one of any character followed by atleast two digit.
how ever im not sure but it seams a paranthesis is missing.
I would try to go here to match the regex
http://www.perlfect.com/articles/regextutor.shtml
the regex is m/($rr)(.+>)(\d.\d+ but this seams wrong /($rr)(.+>)(\d.\d+)/ seams better.
the regex also has capture groups that can be accessed within the if statement with
$_[0] .. $_[2]
I'm trying to search and replace $data['user'] for $data['sessionUser'].
However, no matter what search string I use, I always get a "pattern not found" as the result of it.
So, what would be the correct search string? Do I need to escape any of these characters?
:%s/$data['user']/$data['sessionUser']/g
:%s/\$data\[\'user\'\]/$data['sessionUser']/g
I did not test this, but I guess it should work.
Here's a list of all special search characters you need to escape in Vim: `^$.*[~)+/
There's nothing wrong with with the answers given, but you can do this:
:%s/$data\['\zsuser\ze']/sessionUser/g
\zs and \ze can be used to delimit the part of the match that is affected by the replacement.
You don't need to escape the $ since it's the at the start of the pattern and can't match an EOL here. And you don't need to escape the ] since it doesn't have a matching starting [. However there's certainly no harm in escaping these characters if you can't remember all the rules. See :help pattern.txt for the full details, but don't try to digest it all in one go!
If you want to get fancy, you can do:
:%s/$data\['\zsuser\ze']/session\u&/g
& refers to the entire matched text (delimited by \zs and \ze if present), so it becomes 'user' in this case. The \u when used in a replacement string makes the next character upper-case. I hope this helps.
Search and replace in vim is almost identical to sed, so use the same escapes as you would with that:
:%s/\$data\['user'\]/$data['session']/g
Note that you only really need to escape special characters in the search part (the part between the first set of //s). The only character you need to escape in the replace part is the escape character \ itself (which you're not using here).
The [ char has a meaning in regex. It stands for character ranges. The $ char has a meaning too. It stands for end-line anchor. So you have to escape a lot of things. I suggest you to try a little plugin like this or this one and use a visual search.
I have several php files in directory, I want to replace a few words in all files with different text. It's a part of my code:
$replacements_table=
("hr_table", "tbl_table"),
('$users', "tbl_users")
foreach ($file in $phpFiles){
foreach($replacement in $replacements_table){
(Get-Content $file) | Foreach-Object{$_ -replace $replacement} | Set-Content $file
}
}
It works fine for replacing "hr_table", but doesn't work at all for '$users'. Any suggestion would be nice
The string is actually a regular expression and so needs to be escaped using '\'. See this thread
$replacements_table= ("hr_table", "tbl_table"), ('\$users', "tbl_users")
will work.
The dollar sign is a special regular expression character, matches the end of a string, you need to escape it. Escaping a character in regex is done by a '\' in front of the character you want to escape. A safer method to escape characters (especially when you don't know if the string might contain special characters) is to use the Escape method.
$replacements_table= (hr_table', 'tbl_table'), ([regex]::Escape('$users'), 'tbl_users')
Try escaping "$' with a backslash: '\$users'
The $ symbol tells the regular expression to match at the end of the string. The backslash is the regular expression escape character.
try using double quotes around your variable name instead of single quotes
EDIT
Try something along these lines ....
$x = $x.Replace($originalText, '$user')