Regular expression - parse version number string

Hi,
I try to parse a string using regular expressions but id did not work correctly in all cases.
The string that i want to parse can have one of the following layout:
3.4.5.v20090305 or
3.4.5The first three parts have to be integer values, the last part can be a free string (which is optional).
I use the following code to parse the version number and extract the parts:
Pattern versionPattern = Pattern.compile("(\\d+)\\.{1}(\\d+)\\.{1}(\\d+)(?:\\.{1}(\\w+))?");
Matcher m = versionPattern.matcher(versionString);
if (!m.find()) {
    throw new IllegalArgumentException("Version must be in form <major>.<minor>.<micro>.<qualifier>");
// assert that we matched every part
// three groups (without qualifier) or four parts (with qualifier)
int groups = m.groupCount();
if (groups != 4) {
     throw new IllegalArgumentException("Version must be in form <major>.<minor>.<micro>.<qualifier>");
// extract the parts
major = parseInt(m.group(1));
minor = parseInt(m.group(2));
micro = parseInt(m.group(3));
qualifier = m.group(4);The above regular expression works in all cases that i tested, except one.
The follwoing string is accepted as correct input: (but it shouldn't)
3.4.5a.v20090305And i get the result:
major = 3
minor = 4
micro = 5
qualifier = a.v20090305
Thanks for help or suggestions :)
Best Regards,
Michael

heissm wrote:
Hi,
I try to parse a string using regular expressions but id did not work correctly in all cases.
The string that i want to parse can have one of the following layout:
3.4.5.v20090305 or
3.4.5The first three parts have to be integer values, the last part can be a free string (which is optional).
I use the following code to parse the version number and extract the parts:
Pattern versionPattern = Pattern.compile("(\\d+)\\.{1}(\\d+)\\.{1}(\\d+)(?:\\.{1}(\\w+))?");
Matcher m = versionPattern.matcher(versionString);
if (!m.find()) {
throw new IllegalArgumentException("Version must be in form <major>.<minor>.<micro>.<qualifier>");
// assert that we matched every part
// three groups (without qualifier) or four parts (with qualifier)
int groups = m.groupCount();
if (groups != 4) {
throw new IllegalArgumentException("Version must be in form <major>.<minor>.<micro>.<qualifier>");
// extract the parts
major = parseInt(m.group(1));
minor = parseInt(m.group(2));
micro = parseInt(m.group(3));
qualifier = m.group(4);The above regular expression works in all cases that i tested, except one.
The follwoing string is accepted as correct input: (but it shouldn't)
3.4.5a.v20090305And i get the result:
major = 3
minor = 4
micro = 5
qualifier = a.v20090305No, that can't be the output. Perhaps you have some old class files you're executing, because with the code you now posted, that can't be the result.
To verify this, execute this:
import java.util.regex.*;
public class Main {
    public static void main(String[] args) {
        String versionString = "3.4.5a.v20090305";
        Pattern versionPattern = Pattern.compile("(\\d+)\\.{1}(\\d+)\\.{1}(\\d+)(?:\\.{1}(\\w+))?");
        Matcher m = versionPattern.matcher(versionString);
        if (!m.find()) {
            throw new IllegalArgumentException("Version must be in form <major>.<minor>.<micro>.<qualifier>");
        // assert that we matched every part
        // three groups (without qualifier) or four parts (with qualifier)
        int groups = m.groupCount();
        if (groups != 4) {
             throw new IllegalArgumentException("Version must be in form <major>.<minor>.<micro>.<qualifier>");
        // extract the parts
        System.out.println("1 -> "+m.group(1));
        System.out.println("2 -> "+m.group(2));
        System.out.println("3 -> "+m.group(3));
        System.out.println("4 -> "+m.group(4));
}and you'll see that the following is the result:
1 -> 3
2 -> 4
3 -> 5
4 -> nullSome remarks about your pattern:
"(\\d+)\\.{1}(\\d+)\\.{1}(\\d+)(?:\\.{1}(\\w+))?"All the "{1}" can be omitted they don't add anything to your regex and are only cluttering it up. And you'll probably also want to "anchor" your regex using the start- and end-of-string-meta-characters, like this:
"^(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\w+))?$"

Similar Messages

  • How to write regular expression to find desired string piece *duplicate*

    Hi All,
    Suppose that i have following string piece:
    name:ali#lastname:kemal#name:mehmet#lastname:cemalI need
    ali
    mehmetI use following statement
    SQL> select lst, regexp_replace(lst,'(name:)(.*)(lastname)(.*)','\2',1,1) nm from (
      2    select 'name:ali#lastname:kemal#name:mehmet#lastname:cemal' as lst from dual
      3  );
    LST                                                NM
    name:ali#lastname:kemal#name:mehmet#lastname:cemal ali#lastname:kemal#name:mehmet#
    SQL> But it does not return names correctly. When i change 5th parameter(occurence) of regexp_replace built-in function(e.g. 1,2), i may get ali and mehmet respectiveley.
    Any ideas about regexp?
    Note : I can use PL/SQL instr/substr for this manner; but i do not want to use them. I need regexp.
    Regards...
    Mennan
    Edited by: mennan on Jul 4, 2010 9:53 PM
    thread was posted twice due to chrome refresfment. Please ignore the thread and reply to How to write regular expression to find desired string piece

    The approach is to do cartesian join to a 'number' table returning number of records equal to number of names in the string.I have hardcoded 2 but you can use regexp_count to get the number of occurrences of the pattern in the string and then use level <=regexp_count(..... .
    See below for the approach
    with cte as(
    select
    'name:ali#lastname:kemal#name:mehmet#lastname:cemal' col ,level lev
    from dual connect by level <=2)
    select substr(regexp_substr('#'||col,'#name:\w+',1,lev),7)
    from cte
    /

  • Regular expression - get longest number from string

    I believe it is easy one but I can't get it.Lets say I have a string 'A1_1000' I want to substract the 1000 using regular expression. When I feed Match regular expression I get '1' which is not the longest number. I know other ways of doing that but I want clean solution in one step. Does anybody knows the right regular expression to accomplish that? Thanks!
    LV 2011, Win7
    Solved!
    Go to Solution.

    ceties wrote:
    This is the best solution I was able to come with. I am just wondering if there is "smoother way" without the cycle.
    Since multiple checks are required I would tend to beieve that we do have to loop through the possibilities. in this example
    I start check at offset "0" into the string for a number. Provided i find a number I check if it is longer that any previous number I found and if so save the new longer number in the shift register.
    Have fun!
    Ben
    Message Edited by Ben on 04-15-2009 09:23 AM
    Ben Rayner
    I am currently active on.. MainStream Preppers
    Rayner's Ridge is under construction
    Attachments:
    Find_Longest.PNG ‏33 KB

  • Regular Expressions and Numbers in Strings

    Looking for someone who has had experience in using Regular Expressions in the Classification Rule Builder.
    We have an eVar that is collecting the number of search results in this fashion:
    <Total Results>_<# of Item 1>_<# of Item 2>_<# of Item 3>_<# of Item 4>
    Example output would look like this:
    150_50_0_25_75
    What we've done is initially create a Regular Expression that looks like this:
    ^(.+)\_(.+)\_(.+)\_(.+)\_(.+)$
    The problem is, it appears in situations where the output contains a zero in one of the slots, the value is ignored and it receives the value in the next place over.  Using the example output shown above, I would end up with values like this:
    $0 150_50_0_25_75
    $1 150
    $2 50
    $3 25
    $4 75
    $5 {null}
    Here's the weird part.  When I perform a test of a single record, it appears like it will work just fine, but when it actually runs in Omniture, it's not working as expected.  Here's something else I'd like to know if it's possible to address.  The five-place string is only the newest iteration of this approach.  In the past, we started out with a two-place version, then three-place and then four.  Any recommendations for handling all scenarios?
    Any and all advice is welcome.  Thanks in advance!

    Doing some playing around on rubular.com and thinking the Regular Expression should be build this way instead:
    ^(\d+)\_(\d+)\_(\d+)\_(\d+)\_(\d+)$
    Again, still looking for any additional guidance from more experienced individuals.  Thanks!

  • Regular Expression for Invalid Number

    Hi everyone,
    I am using oracle version as follows:
    SQL> select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
    PL/SQL Release 10.2.0.4.0 - Production
    CORE    10.2.0.4.0      Production
    TNS for 32-bit Windows: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
    I am using regular expression to replace invalid values from a table.
    I received oracle error stating "ORA-01722 invalid number"
    My query looks like this:
    SELECT DISTINCT
    MRC_KEY,
    PURPOSE_CD,
    RESIDENCE_DESC,
    to_number(regexp_replace(ICAP_GEN_MADAPTIVE,'[+. ]?0?0?(\d+)[-.]?','\1')) as ICAP_GEN_MADAPTIVE,
    From
    MRRC_INT
    I am not sure what are the invalid values in the table so I can write regexp accordingly.
    Any guidance is highly appreciated!
    Thanks in advance
    J

    Or use DML error logging:
    create table t1
      (col1 number);
    exec dbms_errlog.create_error_log ('t1','t1_errors')
    insert into t1
    with t as
      (select '1' col from dual union all
       select '1.1' col from dual union all
       select '.11' col from dual union all
       select '0.11' col from dual union all
       select '-1' col from dual union all
       select '1,1' col from dual union all
       select '11a' col from dual union all
       select '1d' col from dual union all
       select '1e6' col from dual union all
       select '1e6.1' col from dual union all
       select '1e' col from dual
    select col
    from t
    log errors into t1_errors
    reject limit 20
    col col1 for 999,999,999.99
    select * from t1;
               COL1
               1.00
               1.10
                .11
                .11
              -1.00
       1,000,000.00
    col col1 for a30
    select * from t1_errors;
    ORA_ERR_NUMBER$ ORA_ERR_MESG$                  ORA_ERR_ROWID$       OR ORA_ERR_TAG$         COL1
               1722 ORA-01722: invalid number                           I                       1,1
               1722 ORA-01722: invalid number                           I                       11a
               1722 ORA-01722: invalid number                           I                       1d
               1722 ORA-01722: invalid number                           I                       1e6.1
               1722 ORA-01722: invalid number                           I                       1e

  • Regular Expression to Check number with at least one decimal point

    Hi,
    I would like to use the REGEX_LIKE to check a number with up to two digits and at least one decimal point:
    Ex.
    10.1
    1.1
    1
    12
    This is what I have so far. Any help would be appreciated. Thanks.
    if regexp_like(v_expr, '^(\d{0,2})+(\.[0-9]{1})?$') t

    Hi,
    Whenever you have a question, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) for all the tables involved, and the results you want from that data.
    Explain, using specific examples, how you get those results from that data.
    Always say what version of Oracle you're using (e.g. 11.2.0.2.0).
    See the forum FAQ: https://forums.oracle.com/message/9362002
    SammyStyles wrote:
    Hi,
    I would like to use the REGEX_LIKE to check a number with up to two digits and at least one decimal point:
    Ex.
    10.1
    1.1
    1
    12
    This is what I have so far. Any help would be appreciated. Thanks.
    if regexp_like(v_expr, '^(\d{0,2})+(\.[0-9]{1})?$') t
    Do you really mean "up to two digits", that is, 3 or more digits is unacceptable?  What if there are 0 digits?  (0 is less than 2.)
    Do you really mean "at least one decimal point", that is, 2, 3, 4 or more decimal points are okay?  Include some examples when you post the sample data and results.
    It might be more efficient without regular expressions.  For example
    WHERE   TRANSLATE ( str              -- nothing except digits and dots
                      , 'A.0123456789'
                      , 'A'
                      )   IS NULL
    AND     str           LIKE '%.%'     -- at least 1 dot
    AND     LENGTH ( REPLACE ( str       -- up to 2 digits
                    )     <= 2

  • Regular expression or format into string (nevermind)

    Solved it,
    I can use string to fractional number!
    Hi,
    I have a 2D string array from a multicolumn list box, and i want to check if every value is valid number, the numbers can be a single and can have negative values. Does anyone knows which regular expression i need to check this, or is there an ever better way doing it?
    Best regards,
    Thijs
    Solved!
    Go to Solution.

    You shoudl post your solution so others who have a similar issue can learn from how you solved it.
    Mark Yedinak
    "Does anyone know where the love of God goes when the waves turn the minutes to hours?"
    Wreck of the Edmund Fitzgerald - Gordon Lightfoot

  • Regular expressions: the shorter the string, the longer the time to analyse

    Hello there !
    I've got a problem with regular expressions...
    I analyse those two strings with the same regular expression, searching for the "message" word.
    The first of them, which is much longer than the other one, is instantly analysed... but the second one takes about to one second !
    Do you see the problem ? (I do not, as you can guess...).
    I tried to put the same special characters in the two ones... but it still works slowly for the second one.
    This is instantly analysed:
    "Coucou----- Origin.a.l. .message -----From: clems= To: Cl�ment S=ent: Wednes=day, April 30, 2003 1:38 PMSubject: Fw: mail de test----- Original Message -----From: clemsTo: Cl�ment Sent: Wednesday, April 30, 2003 1:37 PMSubject: mail de testcoucou, ceci est un mail de t.e.s.t... !!!Clems.".matches("((.*\\W)*\\Q" + "message" + "\\E(\\W.*)*)")
    This takes about to one second:
    "This is a b message ubodyub.brHere s a href= http:www.tano.fr.fm the second linea.".matches("((.*\\W)*\\Q" + crit�reActuel.getLeMot(i).toLowerCase() + "\\E(\\W.*)*)")
    Pleaaase, help ;)
    Clement

    Well in fact everything seems to work... there was another problem...
    My regular expression seems to be wrong and the code too...
    I apologize... sorry for the waste of time.
    See you later :) for my next wrong problem ! :))
    Clement

  • Regular expression- insert into a string phrase "new" into correct position

    I have sample data in table T below, and i have sample output how i want the query to output over that data.
    with T as
    select 'CREATE OR REPLACE PACKAGE BODY "YYY"."PACKAGEONE" IS' s from dual union all
    select 'Create or REPLACE PACKAGE BODY "ZZZ"."PACKAGETWO" IS' s from dual
    select REGEXP_REPLACE(T.s, '^.PACKAGE BODY$','(\1)_new',1,1,'i') as s from T;
    Expected output:
    CREATE OR REPLACE PACKAGE BODY "YYY"."PACKAGEONE_new" IS
    Create OR REPLACE PACKAGE BODY "ZZZ"."PACKAGETWO_new" IS
    */All data has following pattern:
    CREATE OR REPLACE PACKAGE BODY "[owner]"."[name]" ISWhere [owner] can be any string. In sample data we have for example values XXX and YYY there.
    And [name] can be any string. In sample data we have for example values PACKAGEONE and PACKAGETWO there.
    Other parts of the string is fixed and stays as you see.
    As shown in expected output query should replace substring "[owner]"."[name]" to "[owner]"."[name]_new"
    How can i write such query?
    I think i somehow should in regular expression count the positions of double quotes to achieve the expected result, but i don't know how.

    Thx, but your solution doesn't work, it doesn't put phrase "new" into string. I use Oracle 10g.
    with T as
    select 'CREATE OR REPLACE PACKAGE BODY "YYY"."PACKAGEONE" IS...' s from dual union all
    select '...Create or REPLACE PACKAGE BODY "ZZZ"."PACKAGETWO" ..."a"."b" procedure a IS..' s from dual
    select
    RegExp_Replace(s,'(" IS$)','_new\1') as new
    from t;
    CREATE OR REPLACE PACKAGE BODY "YYY"."PACKAGEONE" IS...
    ...Create or REPLACE PACKAGE BODY "ZZZ"."PACKAGETWO" ..."a"."b" procedure a IS..
    {code}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • Regular expression for middle of string

    Bit of background. I'm getting both text (can contain numbers) and data (only numbers) from serial. Since I don't know which I'm receiving and when it starts/ends, I'm making the sender send "textSTART###textSTOP" where "###" is what I want to extract. ### can contain text, numbers, new line, carrige return or whatever.
    The same for data&colon; "dataSTART###dataSTOP", where ### contains only numbers.
    I think I should use Match Pattern, but I don't know how to make my regular expression.
    Any help is appreciated. 
    Solved!
    Go to Solution.

    If the string does not contain anything outside these "delimiters" and there are exactly two per string, you could simply use scan strings for tokens. You can also add the "dataSTART/STOP"  delimiters to the array to make it universal and look at the beginning of the raw string to determine if you are dealing with a "data" or "text" message.
    Here's a quick draft.
    LabVIEW Champion . Do more with less code and in less time .
    Attachments:
    TaggedText.png ‏10 KB

  • Regular Expression for Match Pattern (string) Function

    I need to find a variable length string enclosed by brackets and
    within a string. Can't seem to get the regular expression right for
    the Match Pattern function. I'm able to get the job done using the
    Token function, but it's not as slick or tight as I'd like. Does
    anybody out there have the expression for this?

    Jean-Pierre Drolet wrote in message news:<[email protected]>...
    > The regular expression is "\[[~\]]*\]" which means:
    > look for a bracket "\[" (\ is the escape char)
    > followed by a string not containing a closing bracket "[~\]]*"
    > followed by a closing bracket "\]". The match string include the
    > brackets
    >
    > You can also read "Scan from String" with the following format:
    > "%[^\[]\[%[^\[\]]" and read the 2nd output. The brackets are removed
    > from the scanned string.
    Thanks, Jean_Pierre
    I did some more experimenting after posting and found that \[.*\] also
    works with the match pattern function. Thanks for your input.
    sm

  • Regular Expressions and phone number

    HI,
    there is a column "Phone_number Varchar2"
    Data containing :
    123-89556-6852
    (123)-857-965
    123-(5846)5648
    I want to display that
    123895566852
    123857965
    12358465648
    Pls help by Regular Expressions.
    Edited by: YLN on Feb 17, 2010 3:59 PM

    with t
    as
      select '123-89556-6852' col from dual union all
      select '(123)-857-965' col from dual union all
      select '123-(5846)5648' col from dual
    SELECT regexp_replace(col,'[^[:digit:]]') FROM tRavi Kumar

  • How to write regular expression to find desired string piece

    Hi All,
    Suppose that i have following string piece:
    name:ali#lastname:kemal#name:mehmet#lastname:cemalI need
    ali
    mehmetI use following statement
    SQL> select lst, regexp_replace(lst,'(name:)(.*)(lastname)(.*)','\2',1,1) nm from (
      2    select 'name:ali#lastname:kemal#name:mehmet#lastname:cemal' as lst from dual
      3  );
    LST                                                NM
    name:ali#lastname:kemal#name:mehmet#lastname:cemal ali#lastname:kemal#name:mehmet#
    SQL> But it does not return names correctly. When i change 5th parameter(occurence) of regexp_replace built-in function(e.g. 1,2), i may get ali and mehmet respectiveley.
    Any ideas about regexp?
    Note : I can use PL/SQL instr/substr for this manner; but i do not want to use them. I need regexp.
    Regards...
    Mennan

    Hi, Mennan,
    You can nest REGEXP_SUBSTR withing REGEXP_REPLACE to get the n-th occurrence, like this:
    SELECT     lst
    ,      REGEXP_REPLACE ( REGEXP_SUBSTR ( lst
                                      , 'name:[^#]*#lastname'
                               , 1
                               , n
                     , 'name:(.*)#lastname'
                     , '\1'
                     )      AS nm If the pattern occurs fewer than n times, the expression above returns NULL.

  • Regular expression for Scan from String

    I am trying to pick out three numbers with pattern $number1:number2:number3# from a stream, for instance 8.559509#$-1.686432:-2.427051:-7.281153#$-6.160924​:-1.763356:
    So far, I use "Scan from String" with Format string "$%f:%f:%f #". However I don't know how to ignore/delete the items before $. Would you like to help me with that? Cheers

    You know that your sequence of numbers begins with the $ and ends with the #, so you can separate them into groups first, then separate each number out.
    Bill
    (Mid-Level minion.)
    My support system ensures that I don't look totally incompetent.
    Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.

  • Regular expression not working for String.split()?

    hi, i have a String variable called 'table'.
    It has a bunch of chunks of data seperated by whitespace, whether it
    be spaces or carraige returns. Anyways, i want to split this up using
    the String.split function. i want to split it around whitespace.
    here is my code:
    String codes[] = table.split("\s");
    However, i'm getting back all nulls in the codes variable. What am i doing wrong?
    thanks

    split("\\s")\ is special both in Java String literals and in regex, so you need two of them.
    You'll probably also have to take an extra step it you don't want regex to stop at newlines. I forget the details, so check the docs.

Maybe you are looking for

  • My ipod touch will not open app store help

    My ipod touch will not open the app store. I keeps sayins connot connect to itunes store

  • How do I uninstall Lion and go back to using Snow Leopard

    I installed Lion and it raves havoc with my Epson printer, Microsoft Explorer mouse, and I can't use 2004 MS Word. I just want to it (Lion) GO AWAY!

  • Icloud photo beta not opening

    When I try to open photos from icloud.com, it gives me an error message.No indication of problems on system status page. It has been like that all day. Using Safari, macbook pro early  2013, Yosemite.

  • Why won't a few songs play on my 7th generation ipod nano?

    They do play on my itunes,but I wanted to listen to them on my ipod and they look like they want to play,but they skip to the next song before it would even start.I've tried it many times,but they will not play on my ipod at all.Any helpful advice?

  • Transfer of music to desktop

    I have some non commercial music that I downloaded and put into iTunes. As I have lost the original file I wanted to transfer the music to the desktop so that I could use it as a backing track in iMovie. Is there some way to achieve this? Thank you S