How to do the c# string.split() in oracle - c#

How to remove certain words like DUM or PRJ from begging of string if exists and then split a string based on character _ and take the second part .
For example , if we take
DUM_EI_AO_L_5864_Al Meena Tower I need to get answer as AO and from EI_AE_L_5864_Al radha Tower as AE

Replace the prefixes you want to remove, then find the index of the first and second underscores and then find the substring between those two separators:
Oracle Setup:
CREATE TABLE your_table ( value ) AS
SELECT 'DUM_EI_AO_L_5864_Al Meena Tower' FROM DUAL UNION ALL
SELECT 'EI_AE_L_5864_Al radha Tower' FROM DUAL
Query:
SELECT value,
SUBSTR( replaced_value, first_separator + 1, second_separator - first_separator - 1 )
AS second_term
FROM (
SELECT value,
replaced_value,
INSTR( replaced_value, '_', 1, 1 ) AS first_separator,
INSTR( replaced_value, '_', 1, 2 ) AS second_separator
FROM (
SELECT value,
REPLACE(
REPLACE(
value,
'PRJ_'
),
'DUM_'
) AS replaced_value
FROM your_table
)
)
Output:
VALUE | SECOND_TERM
:------------------------------ | :----------
DUM_EI_AO_L_5864_Al Meena Tower | AO
EI_AE_L_5864_Al radha Tower | AE
Query 2:
You can also use a regular expression:
SELECT value,
REGEXP_SUBSTR( value, '(DUM_|PRJ_)?.*?_(.*?)_', 1, 1, NULL, 2 ) AS second_term
FROM your_table
Output:
VALUE | SECOND_TERM
:------------------------------ | :----------
DUM_EI_AO_L_5864_Al Meena Tower | AO
EI_AE_L_5864_Al radha Tower | AE
db<>fiddle here

Related

Alphanumeric Sorting using SQL Server / C# [duplicate]

This question already has answers here:
Natural (human alpha-numeric) sort in Microsoft SQL 2005
(14 answers)
Closed 5 years ago.
I have alphanumeric numbers. After applying sorting thru SQL Server ORDER BY clause, I get following result
select *
from WO
where WOCode = AnyNumber
order by [ColumnName]
Result:
39660A1
39660A10
39660A11
39660A2
39660A3
39660A4
39660A5
39660A6
39660A7
39660A8
39660A9
Required result
39660A1
39660A2
39660A3
39660A4
39660A5
39660A6
39660A7
39660A8
39660A9
39660A10
39660A11
Here is a quick and dirty solution:
SELECT *
FROM table
ORDER BY LEN(Field) ASC, Field ASC
Demo here.
Assuming that the letter A is always in the same position, and the characters after it are integers only.
Then you can do this:
WITH CTE AS
(
SELECT
WOCode,
CAST(SUBSTRING(WOCode, CHARINDEX('A', WOCode) + 1,
LEN(WOCode) - CHARINDEX('A', WOCode) + 1) AS INT) AS DisplayOrder
FROM
WO
)
SELECT *
FROM CTE
ORDER BY DisplayOrder;
Demo
Results:
| WOCode |
|----------|
| 39660A1 |
| 39660A2 |
| 39660A3 |
| 39660A4 |
| 39660A5 |
| 39660A6 |
| 39660A7 |
| 39660A8 |
| 39660A9 |
| 39660A10 |
| 39660A11 |
You can also use TRY_CAST to avoid errors that might result because of using cast with non integer values (Thanks to #zambonee for suggestion):
WITH CTE AS
(
SELECT
WOCode,
CASE
WHEN TRY_CAST(WOCode AS INT) IS NULL
THEN CAST(SUBSTRING(WOCode,
CHARINDEX('A', WOCode) + 1,
LEN(WOCode) - CHARINDEX('A', WOCode) + 1) AS INT)
ELSE 0
END AS DisplayOrder
FROM
WO
)
SELECT *
FROM CTE
ORDER BY DisplayOrder;
updated demo

How do I make Regex capture only named groups

According to Regex documentation, using RegexOptions.ExplicitCapture makes the Regex only match named groups like (?<groupName>...); but in action it does something a little bit different.
Consider these lines of code:
static void Main(string[] args) {
Regex r = new Regex(
#"(?<code>^(?<l1>[\d]{2})/(?<l2>[\d]{3})/(?<l3>[\d]{2})$|^(?<l1>[\d]{2})/(?<l2>[\d]{3})$|(?<l1>^[\d]{2}$))"
, RegexOptions.ExplicitCapture
);
var x = r.Match("32/123/03");
r.GetGroupNames().ToList().ForEach(gn => {
Console.WriteLine("GroupName:{0,5} --> Value: {1}", gn, x.Groups[gn].Success ? x.Groups[gn].Value : "");
});
}
When you run this snippet you'll see the result contains a group named 0 while I don't have a group named 0 in my regex!
GroupName: 0 --> Value: 32/123/03
GroupName: code --> Value: 32/123/03
GroupName: l1 --> Value: 32
GroupName: l2 --> Value: 123
GroupName: l3 --> Value: 03
Press any key to continue . . .
Could somebody please explain this behavior to me?
You always have group 0: that's the entire match. Numbered groups are relative to 1 based on the ordinal position of the opening parenthesis that defines the group. Your regular expression (formatted for clarity):
(?<code>
^
(?<l1> [\d]{2} )
/
(?<l2> [\d]{3} )
/
(?<l3> [\d]{2} )
$
|
^
(?<l1>[\d]{2})
/
(?<l2>[\d]{3})
$
|
(?<l1> ^[\d]{2} $ )
)
Your expression will backtrack, so you might consider simplifying your regular expression. This is probably clearer and more efficient:
static Regex rxCode = new Regex(#"
^ # match start-of-line, followed by
(?<code> # a mandatory group ('code'), consisting of
(?<g1> \d\d ) # - 2 decimal digits ('g1'), followed by
( # - an optional group, consisting of
/ # - a literal '/', followed by
(?<g2> \d\d\d ) # - 3 decimal digits ('g2'), followed by
( # - an optional group, consisting of
/ # - a literal '/', followed by
(?<g3> \d\d ) # - 2 decimal digits ('g3')
)? # - END: optional group
)? # - END: optional group
) # - END: named group ('code'), followed by
$ # - end-of-line
" , RegexOptions.IgnorePatternWhitespace|RegexOptions.ExplicitCapture );
Once you have that, something like this:
string[] texts = { "12" , "12/345" , "12/345/67" , } ;
foreach ( string text in texts )
{
Match m = rxCode.Match( text ) ;
Console.WriteLine("{0}: match was {1}" , text , m.Success ? "successful" : "NOT successful" ) ;
if ( m.Success )
{
Console.WriteLine( " code: {0}" , m.Groups["code"].Value ) ;
Console.WriteLine( " g1: {0}" , m.Groups["g1"].Value ) ;
Console.WriteLine( " g2: {0}" , m.Groups["g2"].Value ) ;
Console.WriteLine( " g3: {0}" , m.Groups["g3"].Value ) ;
}
}
produces the expected
12: match was successful
code: 12
g1: 12
g2:
g3:
12/345: match was successful
code: 12/345
g1: 12
g2: 345
g3:
12/345/67: match was successful
code: 12/345/67
g1: 12
g2: 345
g3: 67
named group
^(?<l1>[\d]{2})/(?<l2>[\d]{3})/(?<l3>[\d]{2})$|^(?<l1>[\d]{2})/(?<l2>[\d]{3})$|(?<l1>^[\d]{2}$)
try this (i remove first group from your regex) - see demo

Implementing function within a specific column in an sql table

I have a student's table where there are 7
columns: Reg_No(i.e.Register number of
student),Mark1,Mark2,Mark3,Best1,Best2,Total.
The data Reg_No, Mark1, Mark2 and Mark3 are retrieved from database.
Am just looking for a way to select the maximum 2 marks from Mark1, Mark2 and Mark3 and fill
them in Best1 and Best2 columns.
Finally i shoud produce the added result of Mark1 and Mark2 in Total column. Pls suggest me a way.
I am going to assume you would like an SQL answer.
SELECT Reg_No, Mark1, Mark2, MAX(Mark1) AS Best1, MAX(Mark2)
AS Best2, SUM(Mark1 + Mark2) AS Total FROM Students GROUP BY Reg_No,
Mark1, Mark2
This query probably isn't very useful, though, since it mixes aggregated data with the data to be aggregated. If you only need to see each unique student's best and total grades, a better query would be:
SELECT Reg_No, MAX(Mark1) AS Best1, MAX(Mark2) AS Best2,
SUM(Mark1 + Mark2) AS Total FROM Students GROUP BY Reg_No
You need to use greatest and least functions applied on the field values of a row.
Example:
select
#m1 := 55 m1, #m2 := 42 m2, #m3 := 66 m3,
#b1 := greatest( #m1, #m2, #m3 ) b1,
#b2 := ( ( #total := #m1 + #m2 + #m3 )
- ( #b1 + least( #m1, #m2, #m3 ) )
) b2,
#total total;
+----+----+----+------+------+-------+
| m1 | m2 | m3 | b1 | b2 | total |
+----+----+----+------+------+-------+
| 55 | 42 | 66 | 66 | 55 | 163 |
+----+----+----+------+------+-------+
Try this on your students table:
select
Reg_No, Mark1, Mark2, Mark3,
#b1 := greatest( Mark1, Mark2, Mark3 ) Best1,
#b2 := ( ( #total := Mark1 + Mark2 + Mark3 )
- ( #b1 + least( Mark1, Mark2, Mark3 ) )
) Best2,
#total Total
from students
Refer to:
MySQL: GREATEST(value1,value2,...)
Return the largest argument
MySQL: LEAST(value1,value2,...)
Return the smallest argument

X and Y Axis Indices in List<string> for Roguelike

After analyzing a snippet of code from this link (the C# portion), I tried doing this on my own for some practice.
However, I'm confused about how the portion below translates to an X,Y index in the string list, and why the if() statement has the Y index before the X.
if (Map[playerY][playerX] == ' ')
Here's what the list looks like:
List<string> Map = new List<string>()
{
"##########",
"# #",
"# > #",
"# > #",
"# #",
"##########"
};
Any help would be appreciated, thank you in advance!
The first [ ] picks one string from the array. The second [ ] picks a character from the string.
Because strings are arrays themselves, calling an indexer function such as: string[n] will get the character at position n.
So when you are trying to get the character the player is on, you get the Y coordinate by indexing the array of strings, because the first string in the array is the top row of the map.
Y |
------------------
0 | ##########
1 | # #
2 | # > #
3 | # > #
4 | # #
5 | ##########
We then pick out the X by matching it to the character at the X position in the string:
X | 0123456789
------------------
| ##########
| # #
| # > #
| # > #
| # #
| ##########
So [Y,X] will get the appropriate character.
The Y index selects which string, as you would expect from a List. The X index actually picks a character from that string. This wouldn't work on a List of, say, ints, because this example is actually using the [] operator on the List and then using it again on the String the List returns.

Need help with regex to parse expression

I have an expression:
((((the&if)|sky)|where)&(end|finish))
What I need is to put a space between symbols and words so that it ends up like:
( ( ( ( the & if ) | sky ) | where ) & ( end | finish ) )
The regex I came up with is (\w)*[(\&*)(\|*)] which only gets me:
( ( ( ( the& if) | sky) | where) & ( end| finish) )
Could I get a little help here from a resident regex guru please? I will be using this in C#.
Edit: Since you're using C#, try this:
output = Regex.Replace(input, #"([^\w\s]|\w(?!\w))(?!$)", "$1 ");
That inserts a space after any character that matches the following conditions:
Is neither a letter, number, underscore, or whitespace
OR is a word character that is NOT followed by another word character
AND is not at the end of a line.
resultString = Regex.Replace(subjectString, #"\b|(?<=\W)(?=\W)", " ");
Explanation:
\b # Match a position at the start or end of a word
| # or...
(?<=\W) # a position between two
(?=\W) # non-word characters
(and replace those with a space).
You could just add a space after each word and after each non-word character (so look for \W|\w+ and replace it with the match and a space. e.g. in Vim:
:s/\W\|\w\+/\0 /g
You could use:
(\w+|&|\(|\)|\|)(?!$)
which means a word, or a & symbol, or a ( symbol, or a ) symbol, or a | symbol not followed by an end of string; and then replace a match with a match + space symbol. By using c# this could be done like:
var result = Regex.Replace(
#"((((the&if)|sky)|where)&(end|finish))",
#"(\w+|&|\(|\)|\|)(?!$)",
"$+ "
);
Now result variable contains a value:
( ( ( ( the & if ) | sky ) | where ) & ( end | finish ) )

Categories

Resources