我找到了一些关于在字符串中查找单词的第一个实例的信息,但是我试图找到一个单词的第一个实例(实际上是两个,但是在单独的调用中)只有在它之前一些非常具体的文本(由下划线分隔的IP地址)略有不同。此外,这些单词由下划线分隔,因此由于某种原因\b
对我不起作用。
这是一些示例字符串,用于一次测试一行。只应匹配粗体字。
在第二次通话中,我想在这些字符串中匹配不同的单词。
我的正则表达式是POSIX正则表达式(对于PostgreSQL 9.4)。到目前为止,我已经能够运行在http://regexpal.com/这里工作的任何东西了。
即使它不能同时解决所有3个例子,如果它可以解决前两个例子,那将非常有帮助。
编辑:为了绝对清楚,我的意图是用字符'c'替换第一个字符串'card',然后用字母'p'替换第一个字符串'port'而不影响'card'的任何实例'或'端口'没有紧跟数字。这就是为什么我的比赛只需要包含没有相应数字的第一个单词。
答案 0 :(得分:1)
如果您可以使用否定前瞻,则可以使用card((?!port).)*port
将字符串与卡匹配,而不是任何数量的字符后跟端口,然后再次使用卡。
编辑:
如果输入始终采用相同的格式,则可以使用card[0-9]{1,2}_port
更具体。这将使其不与任何其他无关的卡和端口实例匹配
EDIT2:
只匹配第一种情况中的单词,您可以使用正向前瞻:card(?=[0-9]{1,2}_port)
。我不确定你的味道是否允许积极的外观(测试人员没有,但这是在js),但给(?<=card[0-9]{1,2}_)port
一个镜头。如果积极的外观不起作用,您可能需要研究替代方案。
答案 1 :(得分:0)
\b
断言在这种情况下不起作用,因为_
被认为是单词字符。
您可以使用背后的外观:
(?<=_)(card).*?(?<=_)(port)
更具体地说,使用IP地址模式:
(^(?:\d+_){4})(card\d+)_(port\d+)
答案 2 :(得分:0)
我必须分两步解决这个问题。在第一个中,我在开头只匹配了带有IP字符串的行(这排除了像我的第3个例子那样的行)。在第二步中,我使用regexp_replace替换每个单词的第一个匹配。
不幸的是,我完全错过了regexp_replace只替换第一场比赛的事实,除非另有说明&#39; g&#39;标志:
WHEN (SELECT regexp_matches(mystring, '^1(?:[0-9]{1,3}_){4}card[0-9]{1,2}_port[0-9]{1,2}')) IS NOT NULL
THEN regexp_replace(regexp_replace(mystring, 'card', 'c'), 'port', 'p')
虽然我仍然希望我能弄清楚如何在单个表达式中匹配其中一个单词,但我会接受任何可以达到此目的的答案。