regexp - find numbers in a string in any order

前端 未结 2 1423
温柔的废话
温柔的废话 2020-12-19 17:13

I need to find a regexp that allows me to find strings in which i have all the required numbers but only once.

For example:

a <- c(\"12\",\"13\",\         


        
2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-19 17:41

    What i exactly need is to find all 3 digit numbers containing 1 2 AND 3 digits

    Then you can safely use

    grep('^[123]{3}$', a, value=TRUE)
    ##=> [1] "112" "123" "113" "212" "223" "213" "312" "323" "313"
    

    The regex matches:

    • ^ - start of string
    • [123]{3} - Exactly 3 characters that are either 1, or 2 or 3
    • $ - assert the position at the end of string.

    Also, if you only need unique values, use unique.

    If you do not need to allow the same digit more than once, you need a Perl-based regex:

    grep('^(?!.*(.).*\\1)[123]{3}$', a, value=TRUE, perl=T)
    ## => [1] "123" "213" "312"
    

    Note the double escaped back-reference. The (?!.*(.).*\\1) negative look-ahead will check if the string has no repeated symbols with the help of a capturing group (.) and a back-reference that forces the same captured text to appear in the string. If the same characters are found, there will be no match. See IDEONE demo.

    The (?!.*(.).*\\1) is a negative look-ahead. It only asserts the absence of some pattern after the current regex engine position, i.e. it checks and returns true if there is no match, otherwise it returns false. Thus, it does not not "consume" characters, it does not "match" the pattern inside the look-ahead, the regex engine stays at the same location in the input string. In this regex, it is the beginning of string (^). So, right at the beginning of the string, the regex engine starts looking for .* (any character but a newline, 0 or more repetitions), then captures 1 character (.) into group 1, again matches 0 or more characters with .*, and then tries to match the same text inside group 1 with \\1. Thus, if there is 121, there will be no match since the look-ahead will return false as it will find two 1s.

提交回复
热议问题