I have a string column [VEHICLE] that contains row variations of "car", "CAR", "car" and "car1". I'm trying to use a limit data by expression to exclude all of those variations. I've tried Lower([VEHICLE]) ~= "*car*" but it isn't working. Any ideas?
You were very close. In Limit Data Using Expression use this instead.
IF(Lower([Vehicle]) ~= "car*",true,false)
or even better... in case you have car$ or something that isn't a-z
IF(Lower([Vehicle]) ~= "car.*",true,false)
or if you expect something to become before car... like thisCar1 use this:
IF(Lower([Vehicle]) ~= ".*car.*",true,false)
In the second example, . is any character and * is stating match 0 or more of this instance. Without the *, which is what you had, it's stating match 0 or more of instances of... nothing. You just have to give it something to reference.
Remeber ~= uses Regular Expressions
Related
I'm looking for a little help on some Lua. I need some code to match this exact line:
efs.test efs.test.gpg
Here's what I have so far, which matches "efs.test":
if string.match(a.message, "%a+%a+%a+.%%a+%a+%a+%a+") then
print(a.message)
else
print ("Does not match")
end
I've also tried this, which matches:
if string.match(a.message, "efs.test") then
print(a.message)
else
print ("Does not match")
end
But when I try to add the extra text my compiler errors with "Number expected, got string" when running this code:
if string.match(a.message, "efs.test", "efs") then
print(a.message)
else
print ("Does not match")
end
Any pointers would be great!
Thanks.
if string.match(a.message, "%a+%a+%a+.%%a+%a+%a+%a+") then
Firstly, this is a wrong use of quantifiers. From PiL 20.2:
+ 1 or more repetitions
* 0 or more repetitions
- also 0 or more repetitions
? optional (0 or 1 occurrence)
In words, you try to match for unlimited %a+ after you already matched the full word with unlimited %a+
To match efs.test efs.test.gpg - we have 2 filenames I suppose, in a strict sense file names may contain only %w - alphanumeric characters (A-Za-z0-9). This would correctly match efs.test:
string.match(message, "%w+%.%w+")
Going one step further, match efs.test as filename and the following filename:
string.match(message, "%w+%.%w+ %w+%.%w+%.gpg")
While this would match both filenames, you would need to check if matched filenames are the same. We can go one step further yet:
local file, gpgfile = string.match(message, "(%w+%.%w+) (%1%.gpg)")
This pattern will return any <filename> <filename>.gpg where the filenames are equal.
With the use of capture-groups, we capture the filename: it will be returned as the first variable and further represented as %1. Then after the space char, we try to match for %1 (captured filename) followed by .gpg. Since it's also enclosed in brackets, it will become the second captured group and returned as the second variable. Done!
PS: You may want to grab ".gpg" by case-insensitive [Gg][Pp][Gg] pattern.
PPS: File names may contain spaces, dashes, UTF-8 characters etc. E.g. ext4 only forbids \0 and / characters.
string.match optional third argument is the index of the given string to start searching at. If you are looking for exactly efs.test efs.test.gpg in that order with that given spacing, why not just use:
string.match(a.message, "efs%.test efs%.test%.gpg")
If you want to match the entire line containing that substring:
string.match(a.message, ".*efs%.test efs%.test%.gpg.*")
For reference
If you are trying to match that exact line its way easier to just use:
if "efs.test efs.test.gpg" = a.message then
print(a.message)
else
print("string does not match!")
end
Of course this wouldn't find any other strings than this.
Another interpretation I see for your question is that you want to know if it has efs.test in the string, which you should be able to accomplish by doing:
if string.match(a.message, "%w+%.%w+") == "efs.test" then
...
end
Also, look into regex, it's basically the language Lua used to match strings with some exceptions.
Using the standard search function (/) in VIM, is there a way to search using a wildcard (match 0 or more characters)?
Example:
I have an array and I want to find anywhere the array's indices are assigned.
array[0] = 1;
array[i] = 1;
array[index]=1;
etc.
I'm looking for something along the lines of
/array*=
if it's possible.
I think you're misunderstanding how the wildcard works. It does not match 0 or more characters, it matches 0 or more of the preceding atom, which in this case is y. So searching
/array*=
will match any of these:
arra=
array=
arrayyyyyyyy=
If you want to match 0 or more of any character, use the 'dot' atom, which will match any character other than a newline.
/array.*=
If you want something more robust, I would recommend:
/array\s*\[[^\]]\+\]\s*=
which is "array" followed by 0 or more whitespace, followed by anything contained in brackets, followed by 0 or more whitespace, followed by an "equals" sign.
try
array.*
.* makes it mean something or nothing.in array* , * goes to y .
I'm trying to find exact matches of strings in Lua including, special characters. I want the example below to return that it is an exact match, but because of the - character it returns nil
index = string.find("test-string", "test-string")
returns nil
index = string.find("test-string", "test-")
returns 1
index = string.find("test-string", "test")
also returns 1
How can I get it to do full matching?
- is a pattern operator in a Lua string pattern, so when you say test-string, you're telling find() to match the string test as few times as possible. So what happens is it looks at test-string, sees test in there, and since - isn't an actual minus sign in this case, it's really looking for teststring.
Do as Mike has said and escape it with the % character.
I found this helpful for better understanding patterns.
You can also ask for a plain substring match that ignores magic characters:
string.find("test-string", "test-string",1,true)
you need to escape special characters in the pattern with the % character.
so in this case you are looking for
local index = string.find('test-string', 'test%-string')
What is an efficient way in MATLAB to replace/insert one symbol (in series of symbols) with several others that correspond to the one that is being replaced?
For example, consider having a string Eq: Eq = 'A*exp(-((x-xc)/w)^2)'. Is there a way to replace * with .*, / with ./,\ with .\, and ^ with .^ without writing four separate strrep() lines?
Regular expressions will do the job nicely. Regular expressions simply find patterns in text. You specify what kind of pattern you are looking for by a regular expression, and the output gives you the locations of where the pattern occurred.
For our particular case, not only do we want to find where patterns occur, we also want to replace those patterns with something else. Specifically, use the function regexprep from MATLAB to replace matches in a string with something else. What you want to do is replace all *, /, \ and ^ symbols by adding a . in front of each.
How regexprep works is that the first input is the string you're looking at, the second input is a pattern that you're trying to find. In our case, we want to find any of *, /, \ and ^. To specify this pattern, you put those desired symbols in [] brackets. Regular expressions reserve \ as a special symbol to delineate characters that can be parsed as a regular expression but actually aren't. As such, you need to use \\ for the \ character and \^ for the ^ character. The third input is what you want to replace each match with. In our case, we simply want to reuse each matched character, but we add a . at the beginning of the match. This is done by doing \.$0 in the regular expression syntax. $0 means to grab the first token produced by a match... which is essentially the matched symbol from the pattern. . is also a reserved keyword using regular expressions, so we must prepend this symbol with a \ character.
Without further ado:
>> Eq = 'A*exp(-((x-xc)/w)^2)';
>> out = regexprep(Eq, '[*/\\\^]', '\.$0')
out =
A.*exp(-((x-xc)./w).^2)
The pattern we are looking for is [*/\\\^], which means that we want to find any of *, /, \ - denoted as \\ in regex, and \^ - denoted as ^ in regex. We want to find any of these symbols and replace them with the same symbol by adding a . character in front - \.$0.
As a more complicated example, let's make sure that we include all of the symbols you're looking for in a sample equation:
>> A = 'A*exp(-((x-xc)/w)^2) \ b^2';
>> out = regexprep(A, '[*/\\\^]', '\.$0')
out =
A.*exp(-((x-xc)./w).^2) .\ b.^2
I'd go with regexp as in rayryeng's answer. But here's another approach, just to provide an alternative.
ops = '*/\^'; %// operators that need a dot
ii = find(ismember(Eq, ops)); %// find where dots should be inserted
[~, jj] = sort([1:numel(Eq) ii-.5]); %// will be used to properly order the result
result = [Eq repmat('.',1,numel(ii))]; %// insert dots at the end
result = result(jj); %// properly order the result
And a variant:
ops = '*/\^'; %// operators that need a dot
ii = find(ismember(Eq, ops)); %// find where dots should be inserted
jj = sort([1:numel(Eq) ii-.5]); %// dot locations are marked with fractional part
result = Eq(ceil(jj)); %// repeat characters where the dots will be placed
result(mod(jj,1)>0) = '.'; %// place dots at indices with fractional part
The vectorize function already does almost all of what you want except that it does not convert mldivide (\) to ldivide (.\).
By "efficient," do you mean fewer lines of code or faster? Regular expressions are almost always slower than other approaches and less readable. I don't think they're necessary or a good choice in this case. If you only need to convert your string once, then speed is less of a concern than readability (strrep will still be faster). If you need to do it many times, this simple code that you alluded to is 4–5 times faster than regexrep for short strings like your example (and much faster for longer strings):
out = strrep(Eq,'*','.*');
out = strrep(out,'/','./');
out = strrep(out,'\','.\');
out = strrep(out,'^','.^');
If you want one line, use:
out = strrep(strrep(strrep(strrep(Eq,'*','.*'),'/','./'),'\','.\'),'^','.^');
which will also be slightly faster still. Or create your own version of vectorize and call that.
Where regular expressions shine is in more complex cases, e.g., if your string is already partially vectorized: Eq = 'A.*exp(-((x-xc)/w)^2)'. Even still, the vectorize function just uses strrep and then calls strfind to "remove any possible '..*', '../', etc." and replace them with the proper element-wise operators because it's faster (symbolic math strings can get very large, for example).
I'm just playing around with Lua trying to make a calculator that uses string manipulation. Basically I take two numbers out of a string, then do something to them (+ - * /). I can successfully take a number out of x, but taking a number out of y always returns nil. Can anyone help?
local x = "5 * 75"
function calculate(s)
local x, y =
tonumber(s:sub(1, string.find(s," ")-1)),
tonumber(s:sub(string.find(s," ")+3), string.len(s))
return x * y
end
print(calculate(x))
You have a simple misplaced parenthesis, sending string.len to tonumber instead of sub.
local x, y =
tonumber(s:sub(1, string.find(s," ")-1)),
tonumber(s:sub(string.find(s," ")+3, string.len(s)))
You actually don't need the string.len, as end of string is the default value for sub if nothing is given.
EDIT:
You can actually do what you want to do way shorter by using string.match instead.
local x,y = string.match(s,"(%d+).-(%d+)")
Match looks for tries to match the string with the pattern given and returns the captured values, in this case the numbers. This pattern translates to "One or more digits, then as few as possible of any character, then one or more digits". %d is 1 digit, + means one or more. . means any character and - means as few as possible. The values within the parentheses are captured, which means that they are returned.