Removing ending alpha characters from string in XSLT - xslt

I have one requirement related to XSLT.
i want to remove ending alphabets in my final output string.
here is the example:
Input string:0123467AAA
Output :0123467
i.e no ending alphbets.
i m new to xslt creation,any suggestion is very helpful to me.
Thank you all in advance.

With XSLT 1.0 your only real option for this is to write a recursive template. Write a named template that takes the string as a parameter. Test whether the last character is a letter. (You can find the last character by using substring($s, string-length($s)-1, 1), and you can test whether it is a letter by testing translate($s, 'ABCD..XYZ', '') = ''). If the last character is a letter make a recursive call to your template passing the whole string minus the last character as the value of the parameter (again, by using substring()). Otherwise, return the string. Make sure that your recursion terminates if the string is zero length.

Related

Find position of first (from the right) numeric character in a text string

I have these strings:
fghs13412asdf
dfs234245gk
and want to return the position of the last numeric character, like so:
5
3
Perhaps there is something different in LibreOffice than Excel, where I'm seeing all the examples. Here's one that should be straightforward, and is returning an error.
Do you need the position of the first numeric character (as in the heading) or of the last one (as in the body of your question)?
If it's the first one, a simple SEARCH() function using regular expressions should to the trick, e.g. =SEARCH("([:digit:])";A1).
If it's the last one, counted from the start of the string, you can use a different regex (adapted from an answer in the OpenOffice forums by gerard24): =SEARCH("[0-9][^[0-9]]+$";A1).
If you need the position of the last numeric character, counted from the end of the string, just subtract the value calculated in step 2 from the LEN() of the entire string: =LEN(A1)-(SEARCH("[0-9][^[0-9]]+$";A1)).
You'll get a #VALUE! error if there's no numeric character, or if the last character of the input string is numeric. Note that whitespace in the string will be ignored:

Substring in DataWeave up to the occurrence of a character

In DataWeave, how would I substring an input value such that the output is everything up to the occurrence of a character? My input value is something like ABCD_123 and I need to take everything up to the underscore, so my output would be ABCD. The regex that achieves this is /[^_]*/, but I can't find a way to implement this using DataWeave. Any help would be appreciated!
Based on #WiktorStribiżew's comment, the way I solved this was by declaring a function:
%function split(text) text splitBy "_"
And then in my DW mapping, I take the value as:
OUTPUT: split(payload.INPUT)[0]

Find 3 or more repeating charaters in a string

I'm trying to find any occurrences of a character repeating more than 2 times in a user entered string. I have this, but it doesn't go into the if statement.
password = asDFwe23df333
s = re.compile('((\w)\2{2,})')
m = s.search(password)
if m:
print ("Password cannot contain 3 or more of the same characters in a row\n")
sys.exit(0)
You need to prefix your regex with the letter 'r', like so:
s = re.compile(r'((\w)\2{2,})')
If you don't do that, then you'll have to double up on all your backslashes since Python normally treats backlashes like an escape character in its normal strings. Since that makes regexes even harder to read then they normally are, most regexes in Python include that prefix.
Also, in your included code your password isn't in quotes, but I'm assuming it has quotes in your code.
Can't you simply go through the whole string and everytime you found a character equal to the previous, you incremented a counter, till it reached the value of 3? If the character was different from the previous, it would only be a matter of setting the counter back to 0.
EDIT:
Or, you can use:
s = 'aaabbb'
re.findall(r'((\w)\2{2,})', s)
And check if the list returned by the second line has any elements.

<address1/> What value is in address

I have an XSLT statement as follows:
<xsl:when test="address1 != ' '">
My incoming XML the address node is as follows:
<address1/>
The node exists and the xsl statement seems to work sometimes, but it doesn't always work, it is giving me inconsistent results. I am checking the address1 node and if it is spaces, then I check address2 node, if it is not spaces I move it up to address1 output field if address1 input is spaces. Our customers are very inconsistent when entering addresses and our vendor requires address1 to be valid. Thanks for any help.
The problem with checking against a string is that you actually check for text within all descendants of the element, so <foo><bar>test</bar></foo> would fail the test foo = '', because the text test exists within the tree.
A more conclusive test is:
address1[not(text()) and not(*)]
This passes only where there is neither text nor child elements within the address element.
The node is empty.
You are testing for it not being a single space ' ', if it is an empty node the test will succeed.
To test that the node is empty you can do this:
<xsl:when test="address1 = ''">
A self-closing tag should have no content, so checking for '' would be the proper way to go. Doing '[space]' implies that the tag is actually <address1>[space]</address1>, which is no longer self closing.
You're not telling us enough about your code for us to reliably tell you what's wrong with it. Don't be so reticent! There could be all sorts of problems that aren't evident from a tiny snippet, e.g. using the wrong context item.
One piece of advice, though: avoid the "!=" operator (which appeared in your example). Usually you want not(author='') rather than author!=''. They mean the same thing if there is exactly one author element, but they have different meanings if there is no author element or if there is more than one. The expression author!='' is true if there is at least one author element whose value is not the empty string; the expression not(author='') is true if there is no author element whose value is the empty string.
To check if an element's string value is non-empty and non-whitespace-only, use:
string-length(normalize-space(address1)) > 0
The standard XPath function normalize-space($s) takes a string $s as an argument and returns another string produced from $s in which all leading and trailing whitespace characters are removed and any group of adjacent interim whitespace characters is replaced by a single space-character.
This means that the result of normalize-space() when applied on a string that contains only white-space characters, is the empty string (having string-length() of 0).
The XPath expression above is testing if the result of applying the normalize-space() function to the string-value of address1 has positive (> 0) length -- this means that the string value of address1 contains at least one non-whitespace character.

How to replace a string between two substrings in a string in VC++/MFC?

Say I have a CString object strMain="AAAABBCCCCCCDDBBCCCCCCDDDAA";
I also have two smaller strings, say strSmall1="BB";
strSmall2="DD";
Now, I want to replace all occurence of strings which occur between strSmall1("BB") and strSmall2("DD") in strMain, with say "KKKKKKK"
Is there a way to do it without Regex. I cannot use regex as adding another file to the project is prohibited.
Is there a way in VC++/MFC to do it? Or any easy algorithm you can point me to?
int length = strMain.GetLength();
int begin = strMain.Find(strSmall1, 0) + strSmall1.GetLength();
int end = strMain.Find(strSmall2, 0);
CStringT left = strMain.Left(begin);
CStringT right = strMain.Right(length - end);
strMain = left + "KKKKKKK" + right
The easiest way is probably to handle the replacement recursively. Search for the starting delimiter and the ending delimiter. If you find them, put together a new string consisting of the string up to the starting delimiter, followed by the replacement string, followed by the return from recursively doing the replacement in the remainder of the string following the ending delimiter.
That, of course, assumes you want to replace all the occurrences in the main string -- if you only want to replace the first one, John Weldon's solution (for one example) will work quite nicely.
psudocode:
loop over string
if curlocation matches string strsmall1 save index break
loop over remaining string
replace till curlocation matches string strsmall2
Extra credit:
What will the next assignment be?
My answer:
Speed it up by jumping the length of strsmall1 and strsmall2 in loop iterations