Regex 一组不同场景的正则表达式(前面有一个完整单词的第一个句号)

Regex 一组不同场景的正则表达式(前面有一个完整单词的第一个句号),regex,Regex,我有一组可以采用不同格式的字符串。我希望能够得到第一节课的所有内容以及第一节课之前的任何字符(可以是空格、括号、花括号等) 例如: if SCHEMA.COLUMN='XYZ'-应返回SCHEMA SUM(SCHEMA.COLUMN)-应返回SCHEMA [SCHEMA.COLUMN]-应返回SCHEMA 从SCHEMA1.inventory a、SCHEMA2.quantity b(其中a.id=b.id)中选择产品标识解码(仓库标识'Apple'、'APPL'、'Microsoft'、'M

我有一组可以采用不同格式的字符串。我希望能够得到第一节课的所有内容以及第一节课之前的任何字符(可以是空格、括号、花括号等)

例如:

  • if SCHEMA.COLUMN='XYZ'
    -应返回
    SCHEMA
  • SUM(SCHEMA.COLUMN)
    -应返回
    SCHEMA
  • [SCHEMA.COLUMN]
    -应返回
    SCHEMA
  • 从SCHEMA1.inventory a、SCHEMA2.quantity b(其中a.id=b.id
    )中选择产品标识解码(仓库标识'Apple'、'APPL'、'Microsoft'、'MSFT'),但应返回
    SCHEMA1
  • 从SCHEMA1.inventory a、SCHEMA2.quantity b(其中a.id=b.id)中选择product_id decode(warehouse_id.)、'APPL'、'Microsoft'、'MSFT'),但应返回SCHEMA1
如果有一个begin char,但无法获得多个begin char,我可以让正则表达式返回字符串

\((.*?)\.
当字符串为
SUM(SCHEMA.column)

我指的是以前关于这个话题的一些帖子,但这些解决方案都没有成功


有人能建议如何做到这一点吗?

因为OP已将问题更改为匹配点,不包括引号中的点。此外,引号也可以转义

以下是可以使用的正则表达式:

^.*?\b(\w+)\.(?=(?:[^'\\]*'[^'\\]*(?:\\.[^'\\]*)*')*[^'\\]*$)
  • “[^'\]*(?:\\.[^'\]*)*”
    匹配带引号的字符串,忽略字符串中的转义引号
  • (?=…)
    通过断言当前位置前面有0个或多个完全带引号的字符串,确保匹配引号字符串外的点

原始解决方案:

您可以使用此正则表达式并从捕获组#1获取字符串:

正则表达式详细信息:

  • ^
    :开始
  • [^.]*
    :匹配0个或多个包含非点字符的字符
  • \b
    :单词边界
  • (\w+)
    :包含1个以上单词字符的捕获组#1
  • \。
    :匹配一个点
以下内容涵盖了大多数(但不是所有)情况。它标识一个标识符,后跟一个
,用作限定名称中的分隔符。搜索的字符串保存在捕获组#1中

有问题的情况是前面包含
的字符串文本。应该跳过这些。使用正则表达式检测和跳过字符串文本是复杂的,因为通常必须计算匹配的分隔符,并在文本中考虑转义的分隔符

因此,此解决方案可能足以满足您的需求。如果字符串文字的一部分与
\w\.[a-zA-Zè]
匹配,则它将失败,但通常不会发生这种情况:
在标点符号角色中通常后跟一些非字母(例如空格、分隔符)

如果无法在正则表达式引擎中关闭全局行为,此解决方案将生成除第一个匹配之外的其他匹配

更新

以下正则表达式不会正确跳过限定名称的第一个匹配项的第一个匹配项之前的字符串文字:

^[^']*?('[^\\']*((\\.)[^\\']*)*'[^']*?)*\b(\w+)\.(?=[a-zA-Z_])
所需结果在捕获组4中

该模式的工作原理是重复匹配文本和非文本的交替序列(匹配的字符串以其中任何一个开头),作为第一个限定名称的前缀(可能为空)。对两种文字分隔符有一个明显的扩展

虽然模式可行,但我建议彻底考虑在生产代码中使用它的替代方法,因为它在可维护性方面很差。


您是否需要
^[^.]*
?regexp的其余部分与紧跟着
@Barmar的第一个单词匹配:如果未使用
global
标志,则不需要它,但我不知道regex flavor OP正在使用,所以不确定是否可以关闭全局行为。@anubhava-谢谢-只是好奇,如何指定在字符串中查找第二个或第三个句点而不是第一个句点case@Prashanth:若要在第三个点之前查找单词,请使用:
^(?:[^.]*\){2}[^.]*\b(\w+)\。
@anubhava如果
恰好出现在作为模式/对象名称分隔符的第一次出现之前的字符串文字中,则此操作将失败。在第四个测试字符串中,用
仓库id“Apple”
替换
仓库id“Apple”
要查看它,我们不能简单地排除像
'foo.bar'
@anubhava这样的字符串文本,这取决于应用程序,我们可能被允许这样做。一般来说,我们不能,这就是为什么我写“大多数(但不是所有)情况”。此解决方案有其局限性,但在专业方面仍有一定的可维护性。我曾多次遇到
'foo.bar'
类型的情况,因此它不是真正的世界外场景。@anubhava我从未声称这是一个奇怪的场景。
\b(\w+)\.(?=[a-zA-Z_])
^[^']*?('[^\\']*((\\.)[^\\']*)*'[^']*?)*\b(\w+)\.(?=[a-zA-Z_])