Does MATLAB have a strip function for strings? - string

Is there a simple function f such that
f(' hello, world! ' ) == 'hello, world!'
I can strip out the spaces (or any character for that matter) using regexes, but this seems like applying a hammer to the problem. I'd just like to know if there is something simple which I've missed.

No need to use a hammer, simply use strtrim.
From the documentation:
S = strtrim(str) returns a copy of string str with all leading and
trailing white-space characters removed. A white-space character is
one for which the isspace function returns logical 1 (true).

To remove the spaces on the side of the string, use the strtrim command.

Since Matlab version 2016b, you can use the built-in strip() function.
For those who do not have the newer matlab version, here is my self-defined function, which also does not have the limitation of exact one char when strCharacter is passed in as strip()
function result = trim(s,varargin)
% Merge multiple spaces to single space in the middle
% remove trailing/leading spaces
% trim(s [, how [,chars]])
% s: a string
% how: a num 1=left only;
% 2=right only;
% 3=left and right;
% 4 (default)=left and right and merge middle
% chars: if not given (default), space
% if given, remove consecutive character instead
%
if nargin == 1
how = 4;
chars = ' ';
elseif nargin == 2
how = varargin{1};
chars = ' ';
elseif nargin == 3
how = varargin{1};
chars = varargin{2};
end % end if nargin
if strcmp(chars,' '), chars='\s'; end
if how==1
expression = sprintf('^(%s)+',chars);
elseif how==2
expression = sprintf('(%s)+$',chars);
elseif how==3
expression = sprintf('^(%s)+|(%s)+$',chars,chars);
elseif how==4
expression = sprintf('(?<=[(%s)])(%s)*|^(%s)+|(%s)+$',chars,chars,chars,chars);
end % end if how
result = regexprep(s, expression, '');
end

Related

How to remove all characters after first instance of punctuation/blank space?

I have short strings (tweets) in which I must extract all instances of mentions from the text and return a list of these instances including repeats.
extract_mentions('.#AndreaTantaros-supersleuth! You are a true journalistic professional. Keep up the great work! #MakeAmericaGreatAgain')
[AndreaTantaros]
How do I make it so that I remove all text after the first instance of punctuation after '#'? (In this case it would be '-') Note, punctuation can be varied. Please no use of regex.
I have used the following:
tweet_list = tweet.split()
mention_list = []
for word in tweet_list:
if '#' in word:
x = word.index('#')
y = word[x+1:len(word)]
if y.isalnum() == False:
y = word[x+1:-1]
mention_list.append(y)
else:
mention_list.append(y)
return mention_list
This would only work for instances with one extra character
import string
def extract_mentions(s, delimeters = string.punctuation + string.whitespace):
mentions = []
begin = s.find('#')
while begin >= 0:
end = begin + 1
while end < len(s) and s[end] not in delimeters:
end += 1
mentions.append(s[begin+1:end])
begin = s.find('#', end)
return mentions
>>> print(extract_mentions('.#AndreaTantaros-supersleuth! You are a true journalistic professional. Keep up the great work! #MakeAmericaGreatAgain'))
['AndreaTantaros']
Use string.punctuation module to get all punctuation chars.
Remove the first characters while they are punctuation (else the answer would be empty string all the time). Then find the first punctuation char.
This uses 2 loops with opposite conditions and a set for better speed.
z =".#AndreaTantaros-supersleuth! You are a true journalistic professional. Keep up the great work! #MakeAmericaGreatAgain') [AndreaTantaros]"
import string
# skip leading punctuation: find position of first non-punctuation
spun=set(string.punctuation) # faster if searched from a set
start_pos = 0
while z[start_pos] in spun:
start_pos+=1
end_pos = start_pos
while z[end_pos] not in spun:
end_pos+=1
print(z[start_pos:end_pos])
Just use regexp to match and extract part of the text.

Apply backspace within a string

I have a string which includes backspace. Displaying it to the commandline will 'apply' the backspaces such that each backspace and the non-backspace character which immediately precedes it cannot be seen:
>> tempStr = ['aaab', char(8)]
tempStr =
aaa
Yet the deletion operation operation only happens when displaying the string. It still has the backspace character, and the 'b', inside it:
>> length(tempStr)
ans =
5
I'm looking for a minimal (ideally some sort of string processing built in) function which applies the backspace operation:
>>f(tempStr)
ans =
'aaa'
It may also help to know that I have an enumerations class over the alphabet 'a' to 'z' plus ' ' and backspace (to store my own personal indexing of the letters, images associated with each etc.). It'd be real spiffy to have this backspace removal operation be a method of the superclass that acts on a vector of its objects.
You can do it with a simple function using a while loop:
function s = printb(s)
while true
% Find backspaces
I = strfind(s, char(8));
% Break condition
if isempty(I), break; end
% Remove elements
if I(1)==1
s = s(2:end);
else
s(I(1)-1:I(1)) = [];
end
end
and the test gives:
s = [char(8) 'hahaha' char(8) char(8) '!'];
numel(s) % returns 10
z = printb(s) % returns 'haha!'
numel(z) % returns 5
This is not really "minimal", but as far as my knowlegde goes I don't think this is feasible with regular expressions in Matlab.
Best,
Your problem can be solved very elegantly using regular expressions:
function newStr = applyBackspaces(tempStr)
newStr = tempStr;
while (sum(newStr==char(8))>0) % while there is at least one char(8) in newStr do:
tmp = newStr; % work on previous result
if (tmp(1) == char(8)) % if first character is char(8)
newStr = tmp(2:end); % then suppress first character
else % else delete all characters just before a char(8)
newStr = regexprep(tmp,[ '.' char(8)],''); % as well as char(8) itself.
end
end
end
In essence, what my function does is delete the character just before the backspace until there are no more backspaces in your input string tempStr.
To test if it works, we check the output and the length of the string:
>> tempStr = ['abc', char(8), 'def', char(8), char(8), 'ghi']
tempStr =
abdghi
>> length(tempStr)
ans =
12
>> applyBackspaces(tempStr)
ans =
abdghi
>> length(applyBackspaces(tempStr))
ans =
6
Hence, tempStr and applyBackspaces(tempStr) show the same string, but applyBackspaces(tempStr) is the same length as the number of characters displayed.

Evaluate equation but ignore order of mathematical operations and parentheses

I'm trying to write a function that ignores the order of mathematical operations and parentheses. The function just evaluates operators from left to right. (for +-*/^)
Example 1: 5 - 3 * 8^2 returns 256.
Example 2: 4 / 2 - 1^2 + (5*3) returns 18.
Here's what I did:
function out = calc(num)
[curNum, num] = strtok(num, '+-*/^');
out = str2num(curNum);
while ~isempty(num)
sign = num(1);
[curNum, num] = strtok(num, '+-*/^');
switch sign
case '+'
out = out + str2num(curNum);
case'-'
out = out - str2num(curNum);
case '*'
out = out.*str2num(curNum);
case '/'
out = out./str2num(curNum);
case '^'
out = out.^str2num(curNum);
end
end
end
My function doesn't ignore the left to right rule. How do I correct for this?
Your first example fails because you are splitting the string with the +-*/ delimiters, and you omitted the ^. You should change this to +-*/^ in lines 2 and 6.
Your second example fails because you aren't telling your program how to ignore the ( and ) characters. You should strip them before you enter the switch statement.
curNum = strrep(curNum,'(','')
curNum = strrep(curNum,')','')
switch sign
...
This is a way without any switch statements.
str = '4 / 2 - 1^2 + (5*3)'
%// get rid of spaces and brackets
str(regexp(str,'[ ()]')) = []
%// get numbers
[numbers, operators] = regexp(str, '\d+', 'match','split')
%// get number of numbers
n = numel(numbers);
%// reorder string with numbers closing brackets and operators
newStr = [numbers; repmat({')'},1,n); operators(2:end)];
%// add opening brackets at the beginning
newStr = [repmat('(',1,n) newStr{:}]
%// evaluate
result = eval(newStr)
str =
4/2-1^2+5*3
newStr =
((((((4)/2)-1)^2)+5)*3)
result =
18

String Manipulation in Lua: Make the odd char uppercase

I'm trying to do a library in Lua with some function that manipulate strings.
I want to do a function that changes the letter case to upper only on odd characters of the word.
This is an example:
Input: This LIBRARY should work with any string!
Result: ThIs LiBrArY ShOuLd WoRk WiTh AnY StRiNg!
I tried with the "gsub" function but i found it really difficult to use.
This almost works:
original = "This LIBRARY should work with any string!"
print(original:gsub("(.)(.)",function (x,y) return x:upper()..y end))
It fails when the string has odd length and the last char is a letter, as in
original = "This LIBRARY should work with any strings"
I'll leave that case as an exercise.
First, split the string into an array of words:
local original = "This LIBRARY should work with any string!"
local words = {}
for v in original:gmatch("%w+") do
words[#words + 1] = v
end
Then, make a function to turn words like expected, odd characters to upper, even characters to lower:
function changeCase(str)
local u = ""
for i = 1, #str do
if i % 2 == 1 then
u = u .. string.upper(str:sub(i, i))
else
u = u .. string.lower(str:sub(i, i))
end
end
return u
end
Using the function to modify every words:
for i,v in ipairs(words) do
words[i] = changeCase(v)
end
Finally, using table.concat to concatenate to one string:
local result = table.concat(words, " ")
print(result)
-- Output: ThIs LiBrArY ShOuLd WoRk WiTh AnY StRiNg
Since I am coding mostly in Haskell lately, functional-ish solution comes to mind:
local function head(str) return str[1] end
local function tail(str) return substr(str, 2) end
local function helper(str, c)
if #str == 0 then
return ""
end
if c % 2 == 1 then
return toupper(head(str)) .. helper(tail(str),c+1)
else
return head(str) .. helper(tail(str), c+1)
end
end
function foo(str)
return helper(str, 1)
end
Disclaimer: Not tested, just showing the idea.
And now for real, you can treat a string like a list of characters with random-access with reference semantics on []. Simple for loop with index should do the trick just fine.

FoxPro functions which determine if a variable is a character string or a numeric string

I'm looking for a Visual FoxPro function which is similar to the PHP function is_numeric().
I have found this, but I could not use VARTYPE or TYPE because the variable is always a character string which contains digits only.
I found ISDIGIT() function, but the manual says that it only checks the first character.
Determines whether the leftmost character of the specified character
expression is a digit (0 through 9).
ISDIGIT(cExpression)
Parameters
cExpression
Specifies the character expression that ISDIGIT( ) tests. Any
characters after the first character in cExpression are ignored.
I would create my own function using the regular expression object VBScript.RegExp
FUNCTION isNumeric( tcValue )
LOCAL oRE
oRE = CreateObject("VBScript.RegExp")
oRE.Pattern = '^[0-9]+$'
RETURN oRE.test( tcValue )
ENDFUNC
? isNumeric( '123' )
But, is there any function provided by FoxPro for this purpose?
Am I just overlooking?
Also same for ISALHPA() which determines whether the leftmost character in a character expression is alphabetic. I want to check if the variable contain only alphabets.
You can create your own function like this.
FUNCTION IsAllDigits
LPARAMETERS tcSearched, tcOptionalSearch
* tcSearched = the string of characters to test.
* tcOptionalSearch = optional, additional characters to allow.
LOCAL lcSearch
m.lcSearch = "01234567989" + IIF(VARTYPE(m.tcOptionalSearch) = "C", m.tcOptionalSearch, "")
LOCAL lcRemaining
m.lcRemaining = CHRTRAN(m.tcSearched, m.lcSearch, "")
RETURN ( LEN(m.lcRemaining) = 0 )
ENDFUNC
FUNCTION ISNUMERIC
LPARAMETERS cVal
LOCAL llNumeric, lnLen, lcChr, lnDecs, lnVal
llNumeric = VARTYPE(cVal) = "N" && Donkey has sent a numeric value
lnDecs = 0
DO CASE
CASE llNumeric
CASE VARTYPE(cVal)<>"C" && Not a character
OTHERWISE
cVal = ALLTRIM(cVal) && Trim spaces
lnLen = LEN(cVal) && How many characters
llNumeric = .T. && Assume
i = 0
DO WHILE llNumeric AND i<lnLen
i = i+1
lcChr = SUBSTR(cVal,i,1) && Get next char
lnVal = VAL(lcChr)
DO CASE
CASE lcChr = "0" && Allowed
CASE lnVal>0 && 1 - 9 OK
CASE INLIST(lcChr, "-", "+") && Allowed but ONLY at the start
llNumeric = i = 1
CASE lcChr = "." && Decimal point but ONLY one
lnDecs = lnDecs+1
llNumeric = lnDecs = 1
OTHERWISE
llNumeric = .F.
ENDCASE
ENDDO
ENDCASE
RETURN llNumeric
ENDFUNC
This could work for ISDIGIT() or ISALPHA().
Function IsAllDigits(myValue)
lReturn = .t.
FOR i = 1 TO LEN(myvalue)
IF !ISDIGIT( SUBSTR(myValue, i, 1) )
lReturn = .f.
EXIT
ENDIF
ENDFOR
RETURN lReturn
ENDFUNC
How about a one liner?
Function IsNumeric
Lparameters pString
Return m.pString == Chrtran(m.pString, Chrtran(m.pString, "0123456789", ""), "")
EndFunc
You can any other valid characters to "0123456789" like "." or ","
There is more simple to test if a string is numeric or not :
If String="123" => val('String')>0
If String="AB123" => val('String')=0
That's all...
Using only Visual Fox Pro, you can do something like this:
FUNCTION is_numeric(var_name)
error_trigger=.f. &&** first initialization
&&** evaluate("any_char") will generate an error so I'm using TRY-CATCH-ENDTRY
TRY
EVALUATE(var_name)
CATCH &&** evaluate() generates an error then the string is character
WAIT WINDOW "character"
error_trigger=.t. &&** there was an error returned by evaluate()
EXIT && stop and jump after ENDTRY
ENDTRY
IF error_trigger=.f. &&** there was no error returned by evaluate() then the string was numeric
WAIT WINDOW "numeric"
ENDIF
ENDFUNC
Then call to the function:
is_numeric("333") will show: numeric
is_numeric("aaa") will show: character
is_numeric("333a333") will show: character
I hope it will help you

Resources