Product code looks like abcd2343, what to split by letters and numbers

后端 未结 6 899
不知归路
不知归路 2020-12-02 18:34

I have a list of product codes in a text file, on each like is the product code that looks like:

abcd2343 abw34324 abc3243-23A

相关标签:
6条回答
  • 2020-12-02 18:58
    In [32]: import re
    
    In [33]: s='abcd2343 abw34324 abc3243-23A'
    
    In [34]: re.split('(\d+)',s)
    Out[34]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']
    

    Or, if you want to split on the first occurrence of a digit:

    In [43]: re.findall('\d*\D+',s)
    Out[43]: ['abcd', '2343 abw', '34324 abc', '3243-', '23A']
    

    • \d+ matches 1-or-more digits.
    • \d*\D+ matches 0-or-more digits followed by 1-or-more non-digits.
    • \d+|\D+ matches 1-or-more digits or 1-or-more non-digits.

    Consult the docs for more about Python's regex syntax.


    re.split(pat, s) will split the string s using pat as the delimiter. If pat begins and ends with parentheses (so as to be a "capturing group"), then re.split will return the substrings matched by pat as well. For instance, compare:

    In [113]: re.split('\d+', s)
    Out[113]: ['abcd', ' abw', ' abc', '-', 'A']   # <-- just the non-matching parts
    
    In [114]: re.split('(\d+)', s)
    Out[114]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']  # <-- both the non-matching parts and the captured groups
    

    In contrast, re.findall(pat, s) returns only the parts of s that match pat:

    In [115]: re.findall('\d+', s)
    Out[115]: ['2343', '34324', '3243', '23']
    

    Thus, if s ends with a digit, you could avoid ending with an empty string by using re.findall('\d+|\D+', s) instead of re.split('(\d+)', s):

    In [118]: s='abcd2343 abw34324 abc3243-23A 123'
    
    In [119]: re.split('(\d+)', s)
    Out[119]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123', '']
    
    In [120]: re.findall('\d+|\D+', s)
    Out[120]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123']
    
    0 讨论(0)
  • 2020-12-02 19:02

    Try this code it will work fine

    import re
    text = "MARIA APARECIDA 99223-2000 / 98450-8026"
    parts = re.split(r' (?=\d)',text, 1)
    print(parts)
    

    Output:

    ['MARIA APARECIDA', '99223-2000 / 98450-8026']

    0 讨论(0)
  • 2020-12-02 19:05
    import re
    
    m = re.match(r"(?P<letters>[a-zA-Z]+)(?P<the_rest>.+)$",input)
    
    m.group('letters')
    m.group('the_rest')
    

    This covers your corner case of abc3243-23A and will output abc for the letters group and 3243-23A for the_rest

    Since you said they are all on individual lines you'll obviously need to put a line at a time in input

    0 讨论(0)
  • 2020-12-02 19:16

    This function handles float and negative numbers as well.

    def separate_number_chars(s):
        res = re.split('([-+]?\d+\.\d+)|([-+]?\d+)', s.strip())
        res_f = [r.strip() for r in res if r is not None and r.strip() != '']
        return res_f
    

    For example:

    utils.separate_number_chars('-12.1grams')
    > ['-12.1', 'grams']
    
    0 讨论(0)
  • 2020-12-02 19:18
    def firstIntIndex(string):
        result = -1
        for k in range(0, len(string)):
            if (bool(re.match('\d', string[k]))):
                result = k
                break
        return result
    
    0 讨论(0)
  • 2020-12-02 19:22

    To partition on the first digit

    parts = re.split('(\d.*)','abcd2343')      # => ['abcd', '2343', '']
    parts = re.split('(\d.*)','abc3243-23A')   # => ['abc', '3243-23A', '']
    

    So the two parts are always parts[0] and parts[1].

    Of course, you can apply this to multiple codes:

    >>> s = "abcd2343 abw34324 abc3243-23A"
    >>> results = [re.split('(\d.*)', pcode) for pcode in s.split(' ')]
    >>> results
    [['abcd', '2343', ''], ['abw', '34324', ''], ['abc', '3243-23A', '']]
    

    If each code is in an individual line then instead of s.split( ) use s.splitlines().

    0 讨论(0)
提交回复
热议问题