How to replace particular string in JAVA? - java

I have string like
order by o desc,b asc
Here I want to replace o and b columns of this clause by table_o and table_b and output
order by table_o desc, table_b asc
I am using replace function for that but output becomes like
table_order table_by table_o desc,table_b asc
How to solve this problem using regular expression?
One more example
"order by orders desc, bye asc"
should be replaced as
"order by table_orders desc, table_bye asc"

Here is one possible solution. [You might have to tweak spaces around desc asc and , based on your actual SQL]
String str = "select a,b,c * from Table order by o desc,b asc,c,d";
System.out.println(str.replaceAll(
"(.*order by )?(\\w+)( desc| asc)?(,|$)", "$1table_$2$3$4"));
Result
select a,b,c * from Table order by table_o desc,table_b asc,table_c,table_d
Visual Regex
Regex details
(.*order by)? => will match select a,b,c * from Table order by =>back ref $1
(\\w+) => will match column name =>back ref $2
( desc| asc)? => will match desc or asc => back ref $3
(,|$) => will match trailing comma or endof line => back ref $4
Please Note : this solution only works with simple sql queries, and would produce wrong result if the order byclause is part of inner query of a complex SQL. Moreover Regex is not can not ideal tool to parse SQL syntax
See this link Regular expression to match common SQL syntax?
If full-fledged SQL parsing is required, Its better to use either SQL parsers or Parser generators like ANTLR to parse SQL. See this link for list of available ANTLR SQL grammer

If you just want to replace text like that just use these regexes:
" o "
" b "

Probably you are looking for this? Regular Expressions in Java SE & EE Have a look at Regular Expressions chapter that will do the work most of the times.

Simply use a space in the replace function (you do not need a regex).
Pseudo-code:
string = string_replace(string, " o ", " table_o ")
Edit:
After your example, you can but every valid boundary between [ and ]. The regex will then match is. To get back the origional boundary put it between ( and ) and replace it back.
E.g.:
string = regex_replace(string, "([ \t])o([ \t,])", "\1o\2")
\1 and \2 might be different in your regex implementation.
Also I'd suggest clarifying your case so that it is clear what you really want to replace and also take a look at Truth's suggestion of the XY problem.

You can use code like this to convert your text:
String sql = "select o, b, c,d form Table order by orders ,b asc, c desc,d desc, e";
String text = sql.toLowerCase();
String orderBy = "order by ";
int start = text.indexOf(orderBy);
if (start >= 0) {
String subtext = text.substring(start+orderBy.length());
System.out.printf("Replaceed: [%s%s%s]%n", text.substring(0, start), orderBy, subtext.replaceAll("(\\w+)(\\s+(?:asc|desc)?,?\\s*)?", "table_$1$2"));
}
OUTPUT:
Replaceed: [select o, b, c,d form table order by table_orders ,table_b asc, table_c desc,table_d desc, table_e]

Related

Get list of parameter names from native sql expression (regex)

I'm having trouble getting list of all parameters in SQL query using Regex.
Example of the query:
SELECT ... WHERE col1 = :user AND col2 = 'HELLO' OR col3 = :language
To obtain parameters, I use following regex pattern:
Pattern.compile(":([\\w.$]+|\"[^\"]+\"|'[^']+')", Pattern.MULTILINE)
The pattern returns list of parameters correctly:
:user
:language
The problem is with another type of query, where literals might contain character ':'
WHERE col1 = :user AND some_date > '2022-09-26T10:22:55'
The list of parameters for this case is:
:user
:22
:55
Is there any better approach that will not consider contents of literals as parameters?
You could simplify your problem by assuming that a named param in sql is just a word with prefix : and always follows after a space (this is actually not a requirement or always true but might be just good enough to get you acceptable results with as simple of regex as possible)
Pattern.compile(" :\\w+", Pattern.MULTILINE)
--
summary of the comments:
had to match
- foo = :param AND :param = bar AND foo=:param AND :param=bar
- AND FUNC(:param) OR FUNC(0, :param) OR FUNC(:param, 0)
finally this regex with fixed length lookahead and variable length lookbehind was helpful:
Pattern.compile("(?<=[=(])\\s*:[\\w_.]+|:[\\w_.]+(?=\s*[=)])", Pattern.MULTILINE)

TRIM replaces LTRIM/RTRIM

I am fairly new to Oracle.
Is it safe to say that LTRIM(RTRIM(<myVarchar>)) is totally replaceable by TRIM(<myVarchar>) if I want to replace both leading and trailing whitespaces in Oracle 11g?
Also, when I am trying to use this function in my query using JPA, I am getting error "org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node".
Here is the query that I am using:
#Query("Select p from OldPin p WHERE TRIM(p.eeNo) = :accNum and
TRIM(p.pinStatus) = 'A' and TRIM(p.memberType='E') and TRIM(p.sCode) in
('MSHK','MCMG')")
public OldPin findByAccountNum(#Param("accNum") String accNum);
Trim will remove both leading and trailing spaces by default
eg. Trim(' test ') output will be test
If we use Trim(both from ) then it will remove a character from both side
eg.,
Trim(both '1' from '111oracle111') output will be oracle
Trim(leading '1' from '111oracle111') output will be oracle111
Trim(trailing '1' from '111oracle111') output will be 111oracle
Trim(both 'ab' from 'abtechab') - it will throw error, because trim will support single character only
In RTrim and LTrim we can remove any number of character.
Too, you can use
select '%'||replace(' hello world ', ' ' , '')||'%' from dual;
and the output is
%helloworld%

JPA Select query not returning results with one letter word

I have a query that when given a word that starts with a one-letter word followed by space character and then another word (ex: "T Distribution"), does not return results. While given "Distribution" alone returns results including the results for "T Distribution". It is the same behavior with all search terms beginning with a one-letter word followed by space character and then another word.
The problem appears when the search term is of this pattern:
"[one-letter][space][letter/word]". example: "o ring".
What would be the problem that the LIKE operator not working correctly in this case?
Here is my query:
#Cacheable(value = "filteredConcept")
#Query("SELECT NEW sina.backend.data.model.ConceptSummaryVer04(s.id, s.arabicGloss, s.englishGloss, s.example, s.dataSourceId,
s.synsetFrequnecy, s.arabicWordsCache, s.englishWordsCache, s.superId, s.categoryId, s.dataSourceCacheAr, s.dataSourceCacheEn,
s.superTypeCasheAr, s.superTypeCasheEn, s.area, s.era, s.rank, s.undiacritizedArabicWordsCache, s.normalizedEnglishWordsCache,
s.isTranslation, s.isGloss, s.arabicSynonymsCount, s.englishSynonymsCount) FROM Concept s
where s.undiacritizedArabicWordsCache LIKE %:searchTerm% AND data_source_id != 200 AND data_source_id != 31")
List<ConceptSummaryVer04> findByArabicWordsCacheAndNotConcept(#Param("searchTerm") String searchTerm, Sort sort);
the result of the query on the database itself:
link to screenshot
results on the database are returned no matter the letters case:
link to screenshot
I solved this problem.
It was due to the default configuration of the Full-text index on mysql database which is by default set to 2 (ft_min_word_len = 2).
I changed that and rebuilt the index. Then, one-letter words were returned by the query.
12.9.6 Fine-Tuning MySQL Full-Text Search
Use some quotes:
LIKE '%:searchTerm%';
Set searchTerm="%your_word%" and use it on query like this :
... s.undiacritizedArabicWordsCache LIKE :searchTerm ...

After concatenation print new line in SQL

Greeting to all smart people around here !
I'm using concat to retrieving two columns into a single column. Here is my query.
select
concat(booking_startdate, ' ', booking_starttime) as date
from
family_resources_booking_tbl;
This is working fine. After concatenation I just wanted to print booking_starttime into a new line. Is there any way to do that??
You can put a carriage return in your string:
select
concat(booking_startdate, '
', booking_starttime) as date
from
family_resources_booking_tbl;
There might be some circumstances where that won't work. You can use the CHAR() function to insert carriage return (13) and/or line feed (10):
select concat(booking_startdate, CHAR(13), booking_starttime) as date
from
family_resources_booking_tbl;
you can achive it like this also
SELECT
booking_startdate + CHAR(13) + CHAR(10) + booking_starttime AS Date
FROM
family_resources_booking_tbl;

Converting regex query to English keyword query

I am trying to convert a regex query to keyword query, such that the keyword query gives me a superset of the regex query. For example
"host." can convert to "host"
"host ((?10\.6\.2*)) ChuckN*" can convert to "host *", "10 6 ", "Chuck"
"host.* registered.+" can convert to "host*", "registered*"
"10\.64\.2*" can convert to "10 64 *"
For this I am looking for a regex tree whose leaf elements can be combined to get the keyword query. I am trying to access the data structure inside pattern class in java used to store the regex. Please let me know how this could be done or if there is some other way.
System.out.println(
( "host."
+ "\nhost ((?10\\.6\\.2*)) ChuckN*"
+ "\nhost.* registered.+"
+ "\n10\\.64\\.2*"
)
.replaceAll("(.?\\*)", "*")
.replaceAll("\\.\\+", "*")
.replaceAll("\\\\.", " ")
.replaceAll("(\\.?[^A-Za-z0-9 \\*\\n])", "")
);
output
host
host 10 6 * Chuck*
host* registered*
10 64 *
Edit : Last replaceAll line corrected.
You may have to complete the sString in last .replaceAll("sString", "").

Categories