如何从字符串中准确提取6个连续数字

时间:2018-11-15 19:08:18

标签: excel

问题:如何从字符串中准确提取 6个连续数字

示例:

f657674
576767g
tt454656y
465767yy
x1234567
1234567x
n645856g
s-5656-54654657657-6576-46567785-4354
pof-user-201734545435454
4545665
345678
f546576767g
rtryty

应该给予

657674
576767
454656
465767
(blank value)
(blank value)
645856
(blank value)
(blank value)
(blank value)
345678
(blank value)
(blank value)

我尝试过的操作:(A1是第一个字符串的单元格)

=IFERROR(LOOKUP(10^6;MID(A1;ROW(INDIRECT("1:"&LEN(A1)-5));6)+0);"")

然后我将此公式拖到其他行,它会给出:

    657674    (right)
    576767    (right)
    454656    (right)
    465767    (right)
   (blank value)  (right) 
   (blank value)  (right)
    645856    (right)
    657457    (wrong)
    435454    (wrong)
    4545665   (wrong)  
    345678    (right)
    546576767 (wrong)
    (blank value)  (right)

版本:Excel 2016

3 个答案:

答案 0 :(得分:2)

您可能需要UDF而不是内置函数。这应该可以,但是可能需要调整。您的OP中的示例返回345678作为正确的返回值,但是两边都没有字母。因此,我假设您想要:一个连续的6个连续数字 ,或者两个连续的6个连续数字,两侧均带有字母。

将此添加到工作簿模块中,您可以像=return_numbers(A1)那样调用。您可能不一定要add the RegEx Reference到VBEditor。

Function return_numbers(ByVal cel As Range) As String
Dim strPattern As String
Dim regEx As New RegExp

strPattern = "[a-z]\d{6}[a-z]"

With regEx
    .Global = True
    .MultiLine = True
    .IgnoreCase = True
    .Pattern = strPattern
End With

Dim matches As Object
Set matches = regEx.Execute(cel)

If Len(cel) = 6 And IsNumeric(cel) Then
    return_numbers = cel.Value
    Set regEx = Nothing
    Exit Function
End If

If matches.Count <> 0 Then
    return_numbers = Mid(matches.Item(0), 2, Len(matches.Item(0)) - 2)
ElseIf matches.Count = 0 Then
    strPattern = "[a-z]{1}\d{6}$"
    regEx.Pattern = strPattern
    Set matches = regEx.Execute(cel)
    If matches.Count <> 0 Then
        return_numbers = Mid(matches.Item(0), 2, Len(matches.Item(0)) - 1)
    ElseIf matches.Count = 0 Then
        strPattern = "^\d{6}[a-z]{1}"
        regEx.Pattern = strPattern
        Set matches = regEx.Execute(cel)
        If matches.Count <> 0 Then
            return_numbers = Mid(matches.Item(0), 1, Len(matches.Item(0)) - 1)
        End If
    End If
End If

Set regEx = Nothing

End Function

enter image description here

如果您想加快速度,我想如果您切换If/else语句,它可能会运行得更快一些,因为它不会总是运行 正则表达式,如果找到6个孤独数字

编辑:这很笨拙。我确定有更好的正则表达式模式,所以请告诉我。

答案 1 :(得分:2)

灵感来自布鲁斯,但配对到最小

Function ContainsSix(ByVal rng As Range) As String
    Dim re As RegExp
    Dim mc As MatchCollection
    Dim CellValue As Variant

    CellValue = rng.Cells(1, 1).Value2
    Set re = New RegExp
    With re
        .Pattern = "(?:\D|^)(\d{6})(?:\D|$)"
        .Global = True
        .MultiLine = True
        .IgnoreCase = True

        If .Test(CellValue) Then
            Set mc = .Execute(CellValue)
            ContainsSix = mc(0).SubMatches(0)
        End If
    End With
    Set re = Nothing
End Function

对正则表达式的描述:

  • 匹配表达式但不捕获它。 [\ D | ^]
    • 从2个替代品中选择
      • 任何不是数字的字符
      • 行或字符串的开头
  • 一个编号的捕获组。 [\ d {6}]
    • 任何数字,精确地重复6次
  • 匹配表达式但不捕获它。 [\ D | $]
    • 从2个替代品中选择
      • 任何不是数字的字符
      • 行尾或字符串

答案 2 :(得分:1)

import RPi.GPIO as GPIO from time import sleep import random import decimal # motor stuff global Motor1 global Motor2 global Motor3 global p global q global dutyCycle global channel Motor1 = 16 # Input Pin Motor2 = 18 # Input Pin Motor3 = 22 # Enable Pin GPIO.setmode(GPIO.BOARD) GPIO.setup(Motor1,GPIO.OUT) GPIO.setup(Motor2,GPIO.OUT) GPIO.setup(Motor3,GPIO.OUT) p = GPIO.PWM(Motor1,30) q = GPIO.PWM(Motor2,30) p.start(0) q.start(0) dutyCycle = 30 # vibration sensor stuff channel = 40 GPIO.setup(channel, GPIO.IN) def get_wait_time(): waitTime = float(decimal.Decimal(random.randrange(1, 201))/100) return waitTime def do_the_spin(channel): remove_event_detect() i=0 global Motor1 global Motor2 global Motor3 global p global q global dutyCycle timeToSpin = 10 print "\n\nvibration detected! Run the motor!\n\n" while i<timeToSpin: try: print "FORWARD MOTION" q.ChangeDutyCycle(0) p.ChangeDutyCycle(dutyCycle) GPIO.output(Motor3,GPIO.HIGH) waitTime = get_wait_time() i+=waitTime sleep(waitTime) print "BACKWARD MOTION" p.ChangeDutyCycle(0) q.ChangeDutyCycle(dutyCycle) GPIO.output(Motor3,GPIO.HIGH) waitTime = get_wait_time() i+=waitTime sleep(waitTime) print "STOP" print 'i= '+str(i) GPIO.output(Motor3,GPIO.LOW) except KeyboardInterrupt: print "\nCleaning up and closing" p.stop() q.stop() GPIO.cleanup() quit() set_event_detect() def remove_event_detect(): print "remove_event_detect" GPIO.remove_event_detect(channel) def set_event_detect(): print "set_event_detect" GPIO.add_event_detect(channel, GPIO.BOTH, callback=do_the_spin, bouncetime=99) GPIO.add_event_callback(channel, do_the_spin) # assign function to GPIO PIN, Run function on change go_to_sleep() def go_to_sleep(): #GPIO.add_event_detect(channel, GPIO.BOTH, callback=do_the_spin, bouncetime=15000) # let us know when the pin goes HIGH or LOW print "\nWaiting for vibration..." sleep(150000) try: #GPIO.add_event_detect(channel, GPIO.BOTH, callback=do_the_spin, bouncetime=15000) # let us know when the pin goes HIGH or LOW #GPIO.add_event_callback(channel, do_the_spin) # assign function to GPIO PIN, Run function on change #do_the_spin(channel) set_event_detect() except: print "\nCleaning up and closing" p.stop() q.stop() GPIO.cleanup() quit()

请注意,如果您没有使用Excel的英语版本,那么上面的部分内容可能需要修改。

致谢