how to use oracle instr function in java - java

if instr(lv_my_name, ' ', -2) != length(lv_my_name) - 2 or length(lv_my_name) = 2 then
lv_my_name:= lv_my_name;
else
lv_my_name:= trim(substr(lv_my_name, 0, length(lv_my_name)-1));
end if;
if I were to write the same logic in Java, how do I do it?

INSTR(string, substring [, position [, occurrence] ] )
The INSTR functions search string for substring. [...] If a substring that is equal to substring is found, then the function returns an integer indicating the position of the first character of this substring. If no such substring is found, then the function returns zero.
position is an nonzero integer indicating the character of string where Oracle Database begins the search—that is, the position of the first character of the first substring to compare with substring. If position is negative, then Oracle counts backward from the end of string and then searches backward from the resulting position.
occurrence is an integer indicating which occurrence of substring in string Oracle should search for. The value of occurrence must be positive. If occurrence is greater than 1, then the database does not return on the first match but continues comparing consecutive substrings of string, as described above, until match number occurrence has been found.
Compare that to:
String.indexOf(String str, int fromIndex)
Returns the index of the first occurrence of the specified substring, starting at the specified index, or -1 if there is no such occurrence.
String.lastIndexOf(String str, int fromIndex)
Returns the index of the last occurrence of the specified substring, searching backward from the specified index, or -1 if there is no such occurrence.
So, since your code doesn't use 4th parameter, and the 3rd parameter is negative, INSTR and lastIndexOf are mostly equivalent
Remember that Java indexes are 0-based, and Oracle positions are 1-based.

Related

Java regular expression find() matching a zero-length string

The Javadoc for java.util.regex.Matcher.find() says:
This method starts at the beginning of this matcher's region, or, if a
previous invocation of the method was successful and the matcher has
not since been reset, at the first character not matched by the
previous match.
My own experiments suggest that if the regex matches a zero length string, then the method starts one character beyond the end of the previous (zero-length) match. For example, given an input string "abcabc" and a regex "a|b?", successive matches will occur at positions (0, 1, 2, 3, 4, 5, 6). Following a successful match at position 6, there is an unsuccessful match at position 6; and further calls also return false with position remaining at 6.
The documentation suggests that after finding a zero-length match at position 2 (character "c"), the next call on find will start at "the first character not matched", which is still at position 2.
The documentation also suggests that after an unsuccessful match at position 6, the next call should start at position 0, which doesn't appear to be the case.
Is the documentation simply wrong?
Is there a more precise rule somewhere, for example one that covers the behaviour at position 6?
My reason for asking is that I am trying to write an emulation of the method in C#, and I'm having trouble reproducing the precise behaviour by trial and error.
This is a special case handled by Matcher.find():
public boolean find() {
int nextSearchIndex = last;
if (nextSearchIndex == first)
nextSearchIndex++;
// If next search starts before region, start it at region
if (nextSearchIndex < from)
nextSearchIndex = from;
// If next search starts beyond region then it fails
if (nextSearchIndex > to) {
for (int i = 0; i < groups.length; i++)
groups[i] = -1;
return false;
}
return search(nextSearchIndex);
}
If the last match was a zero-length match (indicated by first == last) then it starts the next search at last + 1.
If you think about it this makes sense. Without this, if the Matcher once finds a zero-length match it would never proceed over this match.
So yes, the documentation is incomplete: it neither mentions the special case for zero length matches nor that it only ever passes once over the input string.
But IMHO both special cases are implied by "Attempts to find the next subsequence of the input sequence that matches the pattern."
After a zero length match the next possible subsequence must start one position after the previous match, and the next subsequence can never start at a position lower than the current position (i.e. start over from the beginning).
You can find the OpenJDK implementation of the find method here.
public boolean find() {
int nextSearchIndex = last;
if (nextSearchIndex == first)
nextSearchIndex++;
// If next search starts before region, start it at region
if (nextSearchIndex < from)
nextSearchIndex = from;
// If next search starts beyond region then it fails
if (nextSearchIndex > to) {
for (int i = 0; i < groups.length; i++)
groups[i] = -1;
return false;
}
return search(nextSearchIndex);
}
first and last store the range of the previous successful match, and from and to store the range of the range of the string to be matched.
/**
* The range within the sequence that is to be matched. Anchors
* will match at these "hard" boundaries. Changing the region
* changes these values.
*/
int from, to;
/**
* The range of string that last matched the pattern. If the last
* match failed then first is -1; last initially holds 0 then it
* holds the index of the end of the last match (which is where the
* next search starts).
*/
int first = -1, last = 0;
The behaviours that are relevant to your question are the first and third if statements.
As you can clearly see, the first if checks if the previous match was a 0-length match, and if it is, moves nextSearchIndex one char forward.
The third if checks if nextSearchIndex goes out of range of the string. This happens after you found all 7 matches of "a|b?" in "abcabc".
From what I can see, the documentation doesn't suggest that "after an unsuccessful match at position 6, the next call should start at position 0". At best, the documentation doesn't say anything about what happens after an unsuccessful match.
It could also be argued that "a previous invocation of the method" refers to an invocation of the method at any previous time, not just the immediately prior invocation, in which case what happens after an unsuccessful match is very well-defined:
if there were no previous successful matches at all, start at the beginning
if there was a previous successful match, and it doesn't matter how many failed matches you have since that match, start at the next character not matched by that match.

Does trim() method removes CRLF characters also?

Suddenly noticed that trim() method removes CRLF - new line - characters also..:
String s = "str\r\n";
s = s.trim();
System.out.println("--");
System.out.print(s);
System.out.println("--");
Is it intended to do so?
Yes, see the doc:
Otherwise, let k be the index of the first character in the string
whose code is greater than '\u0020', and let m be the index of the
last character in the string whose code is greater than '\u0020'. A
new String object is created, representing the substring of this
string that begins with the character at index k and ends with the
character at index m-that is, the result of this.substring(k, m+1).
CR+LF: CR (U+000D) followed by LF (U+000A) less than U+0020

Explain the Code and why Subtract the substring

public boolean frontAgain(String str)
{
int len = str.length();
if(len >= 2)
return str.substring(0, 2).equals(str.substring(len-2, len));
else
return false;
}
Can someone please explain why the second substring statement using a word example and a step by step analysis. The program checks if first two letters match the last two letters. for example the word was edited.
str.substring(len-2, len) asks for the last two letters of a string.
To get the last two letters, you need the beginning value of the substring to be the length (5) minus 2 characters, which gives you 3. This is because indexes in Java start at 0. For example, the positions for the characters in the string "horse" are 01234 (i.e. "h" is at index 0, "o" is at index 1 etc.), and the length is 5.
The second parameter of String.subString is for the ending index, which is exclusive. This means the first character position that is not part of the substring you want. In this case, it would be the length because that is 1 character higher than the end of the string.
If you put all that together, you get the following:
String str = "horse"
int length = str.length() // 5
String lastTwoChars = str.substring(length-2, length); // from position 3 to 5
System.out.println(lastTwoChars); // would show you "se"
The documentation for String.substring.

Java String IndexOf behaviour for empty string

For a string say, String str = "abc" both str.indexOf("a") and str.indexOf("") return 0. Is this behaviour valid?
If only there was some place where they document behaviour of methods.
indexOf(string)
Returns the index within this string of the first occurrence of the specified substring.
The returned index is the smallest value k for which:
this.startsWith(str, k)
startsWith(string)
true if the character sequence represented by the argument is a prefix of the character sequence represented by this string; false otherwise. Note also that true will be returned if the argument is an empty string or is equal to this String object as determined by the equals(Object) method.
Yes. The conceptual reason is pretty similar as adding 0 in math. So ""+"a"+"bc" = "abc" = ""+"a"+"b"+""+"c".
The return value of String.indexof("") is 0, or the starting index, when you pass in an empty string because the empty string "" is indeed located there.
Think of "abc" as "" + "abc".
Otherwise, please refer to this documentation:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int)
indexOf "returns:the index of the first occurrence of the character in the character sequence represented by this object, or -1 if the character does not occur."
Therefore, str.indexOf("a") returns 0.
Think of it as
"" +"abc"="abc"
basically
"abc" is ""+"abc"
An empty string does in fact exist in any string that is not null.

what working mechanism of replace() in java

I wrote java program using StringBuilder class.
class StringHandling2
{
public static void main(String args[])
{
StringBuilder sb=new StringBuilder("Welcom");
sb.replace(1,1,"JAVA");
System.out.println(sb);
}
}
I got output that is WJAVAelcome
after i modified index value of replace() in this program,
class StringHandling2
{
public static void main(String args[])
{
StringBuilder sb=new StringBuilder("Welcom");
sb.replace(2,1,"JAVA");
System.out.println(sb);
}
}
jvm throws runtime error that is StringIndexOutofBoundException.
how is replace(int startIndex, int endIndex,string) working in that program?
public StringBuilder replace(int start,
int end,
String str)
Replaces the characters in a substring of this sequence with
characters in the specified String. The substring begins at the
specified start and extends to the character at index end - 1 or to
the end of the sequence if no such character exists. First the
characters in the substring are removed and then the specified String
is inserted at start. (This sequence will be lengthened to accommodate
the specified String if necessary.)
Parameters:
start - The beginning index, inclusive.<br>
end - The ending index, exclusive.<br>
str - String that will replace previous contents.<br>
Returns:
This object.<br>
Throws:
StringIndexOutOfBoundsException - **if start is negative, greater
than length(), or greater than end**.
(source)
sb.replace(2,1,"JAVA");
2 > 1, hence the exception.
It replaces the characters between the start- and end index you specify with the string given in the third argument.
The error is this case comes from the fact that your startindex can't be greater then your end index.
More info can be found here
This is very common concept; according to JavaDoc of replace() method
public StringBuilder replace(int start,
int end,
String str)
Replaces the characters in a substring of this sequence with characters in the specified String. The substring begins at the specified start and extends to the character at index end - 1 or to the end of the sequence if no such character exists. First the characters in the substring are removed and then the specified String is inserted at start. (This sequence will be lengthened to accommodate the specified String if necessary.)
Parameters:
start - The beginning index, inclusive.
end - The ending index, exclusive.
str - String that will replace previous contents.
Returns:
This object.
Throws:
StringIndexOutOfBoundsException - if start is negative, greater than length(), or greater than end.
In your case the start integer is greater that start which would obviously throw ArrayOutOfBoundException.
Edit: and if you are curious why so then the AbstractStringBuilder class is used to replace the characters and this is achieved by creating array of characters in background which is hidden from us.
Good question.
StringBuilder.replace(int start, int end, String s) replaces characters from start index till 1 less than end index by String s.
For eg.
StringBuilder str = new StringBuilder("hello world");
str.replace(0,1,"welcome"); // o/p -welcomeello world
str.replace(2,5,"welcome"); // o/p - hewelcome world
i guess it internally converts string into char[] charArray & replaces char[start] to char[end-1] with string argument value.
So your always end has to greater than start

Categories