Oracle regex for all characters after a specific character - oracle

I need to get all characters after the last 'R' from a part number like this:
223A GHH R337716
So far I've got:
REGEXP_SUBSTR(CUST_PART_NO,'R(.*)')
This returns R337716, but I don't want the 'R' and I'm not sure if it would work if there was more than one 'R' in the string.

Then you have to replace the string with groups of expressions like this:
regexp_replace( CUST_PART_NO, '(.*)(R)(.*)', '\3' )
See it here on sqlfiddle: http://sqlfiddle.com/#!4/3ec77/2
What I'm saying with this expression is:
get everything until R make it as a group 1 expression the first (.*)
get the R make it the second group (R)
get everything else and make it the third group (.*)
The parenthesis on a regular expression define groups of expressions.

What about
ltrim(REGEXP_SUBSTR(CUST_PART_NO,'R(.*)'), 'R')

Related

Regular expression to remove a portion of text from each entry in commas separated list

I have a string of comma separated values, that I want to trim down for display purpose.
The string is a comma separated list of values of varying lengths and number of list entries.
Each entry in the list is formatted as a five character pattern in the format "##-NX" followed by some text.
e.g., "01-NX sometext, 02-NX morertext, 09-NX othertext, 12-NX etc..."
Is there an regular expression function I can use to remove the text after the 5 character prefix portion of each entry in the list, returning "01-NX, 02-NX, 09-NX, 12-NX,..."?
I am a novice with regular expressions and I haven't been able figure out how to code the pattern.
I think what you need is
regexp_replace(regexp_replace(mystring, '(\d{2}-NX)(.*?)(,)', '\1\3'), '(\d{2}.*NX).*', '\1')
The inner REGEXP_REPLACE looks for a pattern like nn-NX (two numeric characters followed by "-NX") and any number of characters up to the next comma, then replaces it with the first and third term, dropping the "any number of characters" part.
The outer REGEXP_REPLACE looks for a pattern like two numeric characters followed by any number of characters up to the last NX, and keeps that part of the string.
Here is the Oracle code I used for testing:
with a as (
select '01-NX sometext, 02-NX morertext, 09-NX othertext, 12-NX etc.' as myString
from dual
)
select mystring
, regexp_replace(regexp_replace(mystring, '(\d{2}-NX)(.*?)(,)', '\1\3'), '(\d{2}.*NX).*', '\1') as output
from a
This alternative calls REGEXP_REPLACE() once.
Match 2 digits, a dash and 'NX' followed by any number of zero or more characters (non-greedy) where followed by a comma or the end of the string. Replace with the first group and the 3rd group which will be either the comma or the end of the string.
EDIT: Took dougp's advice and eliminated the RTRIM by adding the 3rd capture group. Thanks for that!
WITH tbl(str) AS (
SELECT '01-NX sometext, 02-NX morertext, 09-NX othertext, 12-NX etc.' FROM dual
)
SELECT
REGEXP_REPLACE(str, '(\d{2}-NX)(.*?)(,|$)', '\1\3') str
from tbl;

Special character Oracle REGEXP

I need to allow only set of characters i.e.,
a to z A to Z 0 to 9 . !##$% *()_=+|[]{}"'';:?/.,-
but When I add dash(-) character to below query it is not working please help me at earliest.
SELECT :p_string FROM dual
WHERE NOT REGEXP_LIKE (translate(:p_string,chr(10)||chr(11)||chr(13), ' '),'[^]^A-Z^a-z^0-9^[^.^{^}^!^#^#^$^%^*^(^)^_^=^+^|^\^{^}^"^''^;^:^?^/^,^-^ ]' );
[.-.] will work fine on this query .
The extra ^ symbols inside the bracket expression in your pattern are not, as I think you expect, negations; only the first ^ inside the brackets does that.
The main issue that is causing, apart from allowing that actual circumflex symbol to be matched when you didn't seem to want it, is that you end up with ^-^ being treated as a range.
To include a literal - it has to be the first or last thing in the brackets; from the docs:
To specify a right bracket (]) in the bracket expression, place it first in the list (after the initial circumflex (^), if any).
To specify a hyphen in the bracket expression, place it first in the list (after the initial circumflex (^), if any), last in the list, or as an ending range point in a range expression.
So as you need to do both, make the hyphen last; you can change your pattern to:
'[^]A-Za-z0-9[.{}!##$%*()_=+|\{}"'';:?/, -]'
You could also skip the tralsnate step by including those special characters in the pattern too:
'[^]A-Za-z0-9[.{}!##$%*()_=+|\{}"'';:?/, '||chr(10)||chr(11)||chr(13)||'-]'
Looks like you need to permit only (7-bit) ASCII characters with exception of ~ and ^
In this case I would try it like this:
WHERE CONVERT(p_string, 'US7ASCII') = p_string
AND NOT REGEXP_LIKE(p_string, '~|\^')
Instead of CONVERT(p_string, 'US7ASCII') = p_string you can also use ASCIISTR(REPLACE(p_string, '\', '/')) = REPLACE(p_string, '\', '/')

Ruby Regex Match Between "foo" and "bar"

I have unfortunately wandered into a situation where I need regex using Ruby. Basically I want to match this string after the underscore and before the first parentheses. So the end result would be 'table salt'.
_____ table salt (1) [F]
As usual I tried to fight this battle on my own and with rubular.com. I got the first part
^_____ (Match the beginning of the string with underscores ).
Then I got bolder,
^_____(.*?) ( Do the first part of the match, then give me any amount of words and letters after it )
Regex had had enough and put an end to that nonsense and crapped out. So I was wondering if anyone on stackoverflow knew or would have any hints on how to say my goal to the Ruby Regex parser.
EDIT: Thanks everyone, this is the pattern I ended up using after creating it with rubular.
ingredientNameRegex = /^_+([^(]*)/;
Everything got better once I took a deep breath, and thought about what I was trying to say.
str = "_____ table salt (1) [F]"
p str[ /_{3}\s(.+?)\s+\(/, 1 ]
#=> "table salt"
That says:
Find at least three underscores
and a whitespace character (\s)
and then one or more (+) of any character (.), but as little as possible (?), up until you find
one or more whitespace characters,
and then a literal (
The parens in the middle save that bit, and the 1 pulls it out.
Try this: ^[_]+([^(]*)\(
It will match lines starting with one or more underscores followed by anything not equal to an opening bracket: http://rubular.com/r/vthpGpVr4y
Here's working regex:
str = "_____ table salt (1) [F]"
match = str.match(/_([^_]+?)\(/)
p match[1].strip # => "table salt"
You could use
^_____\s*([^(]+?)\s*\(
^_____ match the underscore from the beginning of string
\s* matches any whitespace character
( grouping start
[^(]+ matches all non ( character at least once
? matches the shortest possible string (non greedy)
) grouping end
\s* matches any whitespace character
\( find the (
"_____ table salt (1) [F]".gsub(/[_]\s(.+)\s\(/, ' >>>\1<<< ')
# => "____ >>>table salt<<< 1) [F]"
It seems to me the simplest regex to do what you want is:
/^_____ ([\w\s]+) /
That says:
leading underscores, space, then capture any combination of word chars or spaces, then another space.

Help with regular expression

I have the following lines I have to match
A
Ab
A#
F#7+9d
G3+9d
Gm
Basically I need to match the first letter and the # or the b following. I also need to match anything else (such as the 7+9d or the m).
Here is my code so far but it's not picking up the second part
preg_match('/A-G([A-Z0-9+]?)/i', $start_key, $matches)
Any ideas?
Try this
/^A-G(#|b)?([A-Z0-9+]*)$/i
Try adding a-z and # to the body of the character set, converting your statement into:
preg_match('/A-G([A-Za-z0-9+#]?)/i', $start_key, $matches)

regular expression extract string between two strings

I am trying to extract strings using regexp. For example in the following string:
select DESCENDANTS([Customer].[Yearly Income],,LEAVES) on axis(0),
DESCENDANTS([Sales Territory].[Sales Territory],,LEAVES) on axis(1),
DESCENDANTS([Customer].[Total Children],,LEAVES) on axis(2)
from [Adventure Works]
where [Measures].[Internet Sales Amount]
I want to extract the substring between every pair of "DESCENDANTS(" and ",,".
So the result in this case would be: [Customer].[Yearly Income], [Sales Territory].[Sales Territory], [Customer].[Total Children]
Any help is appreciated. Thanks in advance.
If you have your text in a string called query you can do:
query.scan(/DESCENDANTS\((.+),,/).flatten
=> ["[Customer].[Yearly Income]", "[Sales Territory].[Sales Territory]",
"[Customer].[Total Children]"]
Some notes:
\( matches the literal open bracket
(.+) remembers the characters between the open bracket and the two commas as a capture
If the regexp contains captures () then scan will return an array of arrays of the captured parts for each match. In this case there is only 1 capture per match so flatten can be used to return a single array of all the matches we are interested in.
/DESCENDANTS\(([^,]+),,/
See it on rubular
Here's an uglier variation that uses split: split on "DESCENDANTS(" and ",,", and take every other substring:
s.split(/DESCENDANTS\(|,,/).each_with_index.inject([]) {|m,(e,i)| m << e if i.odd?; m}
.+? is more safe, it works correctly if SQL is in one line.
query.scan(/DESCENDANTS\((.+?),,/).flatten

Resources