How do I match strings in shell-style using Perl? - perl

How to match strings in shell-style in Perl? For instance:
foo*
{bar,baz}.smth
joe?
foobar[0-9]

Using regular expressions
Your examples would be:
/foo.*(bar|baz)\.smth joe/
/foobar\d/
However, if what you actually wanted was shell-like filename expansion (e.g. the above was in context of ls foobar[0-9] ), use glob() function:
my #files = glob("foo* {bar,baz}.smth joe");
my #foobar_files = glob("foobar[0-9]");
Please note that the syntax of regular expressions in Perl is NOT that of filename expansion language

File::FnMatch exposes your system's fnmatch(3) implementation, which is probably what implements the shell's wildcard patterns for you.
(Note that {bar,baz}.smth is not matching per se, it is simply "brace expansion" of strings.)

Related

Powershell function reference and naming conventions

I recently discovered that you can get powershell's functions by reference using the modifier $function:. But I noticed a strange problem...
By convention, POSH uses a {Verb}-{Noun} convention for function names, where {Verb} is part of aproved POSH verb names. For instance: Get-Member or Invoke-WebRequest.
The thing is, that calling $function:Get-Member, for example, is not valid because of the hyphen; it works just fine if you declare a function like ShowMessage and calls: $fn = $function:ShowMessage. So I'd like to know if there's a way to escape this call.
PS.: I do know of another option, but is much much more verbose:
function Show-Message { Write-Host "Foo"; }
$fn = (Get-Item "function:Show-Message").ScriptBlock;
$fn.Invoke();
Update: Although #PetSerAl was very helpfull and explained the problem, I'll mark #Ansgar Wiechers's response as the answer because it's better documented.
function: is a PSDrive, not a (scope)modifier. As for using it with variable-like notation ($function:name): the rules for variable names with special characters apply here as well.
From the documentation:
VARIABLE NAMES THAT INCLUDE SPECIAL CHARACTERS
Variable names begin with a dollar sign. They can include alphanumeric characters and special characters. The length of the variable name is limited only by available memory.
Whenever possible, variable names should include only alphanumeric characters and the underscore character (_).Variable names that include spaces and other special characters, are difficult to use and should be avoided.
To create or display a variable name that includes spaces or special characters, enclose the variable name in braces. This directs PowerShell to interpret the characters in the variable name literally.
Your notation should thus look like this:
${function:Show-Message}
It can be invoked like this:
& ${function:Show-Message}

Warning Control Character '\S' is not valid when concatinating two strings

I have two variables such as:
path='data\voc11\SegmentationClassExt\%s.png'
name='123'
I want to concatenate two strings into one like so:
data\voc11\SegmentationClassExt\123.png
I used the code below:
sprintf(path, name)
However I receive the following error:
Warning: Control Character '\S' is not valid. See 'doc sprintf' for control characters valid in the format string.
ans =
dataoc11
I am using MATLAB on Windows. Could you give me any solution for that. I tried to change path='data\\voc11\\SegmentationClassExt\\%s.png' and when I did that, the above code will work. However, the current data is
path='data\voc11\SegmentationClassExt\%s.png';
use the matlab function fullfile
filename = fullfile ( path, [name '.png'] );
or
filename = fullfile ( path, sprintf ( '%s.png', name ) );
Note: you should avoid using path as a variable as it is already a Matlab function
Before we start, it's highly advised that you do not use path as a local variable. path is a global variable that MATLAB uses to resolve function scope, especially if you are going to use any functions from toolboxes. Overwriting path with your own string will actually make MATLAB not function properly. Use a different variable name.
Now to resolve your problem, you can use either fullfile as what #matlabgui has suggested, or if you don't care about OS compatibility and are only working in Windows, you can either manually change the path as you have placed so that you can introduce two back slashes and it will indeed work on Windows OS, or you can perhaps use a string replace function so that all back slashes will be accompanied with an additional back slash.
Either one of these two methods will work:
Method 1 - Using regular expressions
pat = 'data\voc11\SegmentationClassExt\%s.png';
pat_new = regexprep(pat, '\\', '\\\\');
The function regexprep performs a string replacement by regular expressions. We search for all single backslashes and replace them with double backslashes. Note that the single back slash \ is a special character in regular expressions so if you explicitly what to look for back slashes, you must place an additional back slash beside it.
Method 2 - Using strrep
pat = 'data\voc11\SegmentationClassExt\%s.png';
pat_new = strrep(pat, '\', '\\');
strrep stands for String Replace. It works very similar to regular expressions as we have discussed above. However, what's nice is that you don't have to append an additional back slash when looking for the actual character.
Once you do this, you can use sprintf as normal:
pat_new = sprintf(pat_new, name);

Coffeescript Regex interpolation

Coffeescript supports strings interpolation:
user = "world"
greeting = "Hello #{user}!"
Is it possible to use interpolation in regex just like in strings? E.g.
regex = /Hello #{user}/g
P.S. I know that I can use RegExp(greeting, 'g'), I just want a bit cleaner code.
Block Regular Expressions (Heregexes) support interpolation.
Block Regular Expressions
Similar to block strings and comments,
CoffeeScript supports block regexes — extended regular expressions
that ignore internal whitespace and can contain comments and
interpolation. Modeled after Perl's /x modifier, CoffeeScript's block
regexes are delimited by /// and go a long way towards making complex
regular expressions readable.
This coffeescript code:
name="hello"
test=///#{name}///
compiles to
var name, test;
name = "hello";
test = RegExp("" + name);

How to create a string from a pre-processor macro

I have a preprocessor macro that represents a hierarchical path into my design.
Example:
`define HPATH top.chip.block
I need to construct a string which holds the value of `HPATH, so in my example the string should equal top.chip.block.
Is there a way to construct such a string?
None of the following attempts worked:
string hpath;
hpath = "`HPATH"; // Results in hpath = "`HPATH"
hpath = \"``HPATH\"; // Doesn't compile
hpath = `HPATH; // Doesn't compile
I want hpath to be equivalent to doing this assignment hpath = "top.chip.block", but by using `HPATH instead of specifying the path again.
I cannot use %m because I need the string within my top-level UVM environment, not within a module.
A little more background: the reason I want to do this is because I am using backdoor register access in the UVM class library. The backdoor API requires setting the hdl_path to the blocks within the design, as a string. I already have `defines for the hierarchical paths and am trying to reuse those when specifying the hdl_paths so I don't have the same path defined twice. My testbench will use both the hierarchical path and the string path.
It's not possible to use a `define macro within a string literal. According to the SystemVerilog LRM:
Macro substitution and argument substitution shall not occur within string literals.
However a string literal can be constructed by using a macro that takes an argument and including the quotes in the macro by using ``"`.
Again, from the LRM:
An `" overrides the usual lexical meaning of " and indicates that the expansion shall include the quotation
mark, substitution of actual arguments, and expansions of embedded macros. This allows string literals to be
constructed from macro arguments.
So this works:
`define STRINGIFY(x) `"x`"
`define HPATH top.chip.block
string hpath = `STRINGIFY(`HPATH);
$display(hpath); // Output: "top.chip.block"
The example code can be run here: http://www.edaplayground.com/s/4/879
I know this is an old thread, but I thought I'd share our solution. The use of the $sformatf allows additional information to be added if needed.
`define STRINGIFY(DEFINE) $sformatf("%0s", `"DEFINE`")
I think this is what you're looking for.
`define HPATH `"top.chip.block`"
string hpath = `HPATH;
As toolic pointed out, the escape sequence %m will give you the current hierarchy when used in a $display statement so that may be a better option.

Why does the Perl CGI module use hyphens to start named arguments?

I am a novice. My question is what is the "-" before the keys (type, expires name etc) standing for? Why not just use the plain hash table way and discard the hyphen?
# #!/usr/local/bin/perl -w
use CGI;
$q = CGI->new;
print $q->header(-type=>'image/gif',-expires=>'+3d');
$q->param(-name=>'veggie',-value=>'tomato');
The author already explained in the documentation.
Most CGI.pm routines accept several
arguments, sometimes as many as 20
optional ones! To simplify this
interface, all routines use a named
argument calling style that looks like
this:
print
$q->header(-type=>'image/gif',-expires=>'+3d');
Each argument name is preceded by a
dash. Neither case nor order matters
in the argument list. -type, -Type,
and -TYPE are all acceptable. In
fact, only the first argument needs to
begin with a dash. If a dash is
present in the first argument, CGI.pm
assumes dashes for the subsequent
ones.
Several routines are commonly called
with just one argument. In the case
of these routines you can provide the
single argument without an argument
name. header() happens to be one of
these routines. In this case, the
single argument is the document type.
print $q->header('text/html');
See perlop:
If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. Otherwise, if the string starts with a plus or minus, a string starting with the opposite sign is returned. One effect of these rules is that -bareword is equivalent to the string "-bareword". (emphasis mine)
This is just an older style of perl arguments that isn't usually used in newer modules. It's not exactly deprecated, it's just an older style based on how Perl allows you to not quote your hash keys if they start with a dash.
I don't know what you mean by the 'plain hashtable way'. The way CGI::pm is implemented, names of properties are (in most cases) required to be preceded by '-', presumably so that they can be identified.
Or to put it another way, the hash-key required by CGI::header to identify the 'type' property is '-type'.
That's just the way CGI.pm is defined.