【问题标题】:Recognize numbers in french format inside document using regex使用正则表达式识别文档中法语格式的数字
【发布时间】:2011-11-21 10:26:06
【问题描述】:

我有一份文档,其中包含各种格式的数字,法语、英语、自定义格式。

我想要一个只能捕获法语格式数字的正则表达式。

这是我要捕获的数字的完整列表(d 代表一个数字,小数分隔符是逗号 ,,千位分隔符是空格)

d,d d,dd   d,ddd

dd,d   dd,dd   dd,ddd

ddd,d   ddd,dd   ddd,ddd

d ddd,d   d ddd,dd   d ddd,ddd

dd ddd,d  dd ddd,dd  dd ddd,ddd

ddd ddd,d  ddd ddd,dd  ddd ddd,ddd

d ddd ddd,d...

dd ddd ddd,d...

ddd ddd ddd,d...

这是我的正则表达式

(\d{1,3}\s(\d{3}\s)*\d{3}(\,\d{1,3})?|\d{1,3}\,\d{1,3})

捕捉像上面这样的法语格式,所以我在正确的轨道上,但也像d,ddd.dd(因为它捕捉到d,ddd)或d,ddd,ddd(因为它捕捉到d,ddd)这样的数字。

我应该在我的正则表达式中添加什么?

我拥有的 VBA 代码:

Sub ChangeNumberFromFRformatToENformat()

Dim SectionText As String
Dim RegEx As Object, RegC As Object, RegM As Object
Dim i As Integer

Set RegEx = CreateObject("vbscript.regexp")
With RegEx
    .Global = True
    .MultiLine = False
    .Pattern = "(\d{1,3}\s(\d{3}\s)*\d{3}(\,\d{1,3})?|\d{1,3}\,\d{1,3})"
    ' regular expression used for the macro to recognise FR formated numners
    End With

For i = 1 To ActiveDocument.Sections.Count()

    SectionText = ActiveDocument.Sections(i).Range.Text

    If RegEx.test(SectionText) Then
        Set RegC = RegEx.Execute(SectionText)
        ' RegC regular expresion matches collection, holding french format numbers

        For Each RegM In RegC

            Call ChangeThousandAndDecimalSeparator(RegM.Value)

        Next 'For Each RegM In RegC

        Set RegC = Nothing
        Set RegM = Nothing

    End If

Next 'For i = 6 To ActiveDocument.Sections.Count()

Set RegEx = Nothing

End Sub

用户stema,给了我一个很好的解决方案。正则表达式应该是:

(?

但是 VBA 抱怨正则表达式有未转义的字符。我在 (?: \d{3}) 之间找到了一个 (?: \d{3}),它是一个空白字符,所以我可以用 \s 替换它。我认为第二个是 (?:,\d{1,3}) 在 ?: 和逗号字符 \d 之间,如果我转义它将是 \, .

所以现在正则表达式是 (?

帖子中的新行: 我刚刚发现 VBA 不同意这个正则表达式序列 ?

【问题讨论】:

  • 这真的是您想要捕捉的完整数字列表吗?还是代表名单?如果你必须指定“我认为你得到了图片”,那么听起来像后者。
  • IMO,在包含 d,ddd.dd 的文本中匹配 d,ddd 是完全合法的。如果你想禁止这种结构,只需表达什么是格式错误的数字:格式正确的后面不应该...
  • 最后两个例子看起来像英文格式的数字,但我们怎么知道其余的都是法文呢?谁说100,001一百点零零一(法语)而不是十万零一(英语)?除非能在文中找到更多线索,否则我认为你运气不好。
  • @Po' Lazarus : 错误号码 : d,ddd.d, d,ddd.dd d,ddd.ddd d,ddd,ddd 帮助?非常感谢您的所有时间和帮助!
  • @艾伦摩尔:完全正确。但是我怎样才能最大限度地减少对其他数字的破坏,例如 d,ddd.d, d,ddd.dd d,ddd.ddd d,ddd,ddd ?感谢您的所有时间和支持

标签: regex vba ms-word


【解决方案1】:

这个怎么样?

\b\d{1,3}(?: \d{3})*(?:,\d{1,3})?\b

here on Regexr

\b 是单词边界

首先 (\d{1,3}) 匹配 1 到 3 位数字,然后可以有 0 组或多组前导空格后跟 3 位数字 ((?: \d{3})*),最后可以有一个可选的小数部分 (@987654327 @)

编辑:

如果您想避免使用1,111.1,那么\b 锚对您不利。试试这个:

(?<=^|\s)\d{1,3}(?: \d{3})*(?:,\d{1,3})?(?=\s|$)

Regexr

这个正则表达式现在需要一个空格或字符串的开头,以及一个空格或字符串的结尾,以匹配数字。

编辑 2:

由于不支持向后看,您可以更改为

(?:^|\s)\d{1,3}(?: \d{3})*(?:,\d{1,3})?(?=\s|$)

这不会改变字符串开头的任何内容,但如果数字以前导空格开头,则现在将其包含在匹配中。如果首先将匹配结果用于某些内容,则必须删除前导空格(我很确定 VBA 确实有一种方法(尝试trim())。

【讨论】:

  • 你好,我尝试将正则表达式与 1,111.1 进行匹配,并且成功了。这是一种我不想抓住的数字。有什么新想法吗?非常感谢您的时间和支持!
  • @stema:我刚刚检查了我现在能想到的所有格式错误的数字,它完全有效。我将在文档上对其进行测试并让您知道。非常感谢您的时间和支持
  • @stema:我无法测试它.. VBA 抱怨正则表达式有未转义的字符。我在 (?: \d{3}) 之间找到了一个 (?: \d{3}),它是一个空白字符,所以我可以用 \s 替换它。我认为第二个是 (?:,\d{1,3}) 在 ?: 和 \d 之间,逗号字符,如果我转义它将是 \, 。所以正则表达式现在是 (?
  • @RaduPuspana 空格和逗号不需要转义。但可能是您需要双重转义特殊字符。所以在我原来的正则表达式中尝试\\s 而不是\s\\d 而不是\d
  • @RaduPuspana 抱歉,我不知道。我会尝试逐步测试未转义字符是什么。首先尝试仅匹配\d,然后尝试\d{3},然后添加越来越多的字符,直到找到可能需要转义的字符。
【解决方案2】:

如果您是逐行阅读,您可能会考虑在您的正则表达式中添加锚点(^$),这样您最终会得到如下结果:

^(\d{1,3}\s(\d{3}\s)*\d{3}(\,\d{1,3})?|\d{1,3}\,\d{1,3})$

这指示 RegEx 引擎从行首开始匹配直到最后。

【讨论】:

  • 在我的情况下它不起作用。我将在一分钟内提供更多细节。感谢您的时间和支持
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
相关资源
最近更新 更多