JScript Regex - 提取以子字符串开头的日期
JScript Regex - extract dates preceded by substrings
我有一个包含多个日期的单行字符串。在 JScript Regex 中,我需要提取按给定顺序由“dat”和“wy”的不区分大小写的子字符串处理的日期。子字符串之前和之后可以是任何字符(新行除外)。
reg = new RegExp('dat.{0,}wy.{0,}\d{1,4}([\-/ \.])\d{1,2}([\-/ \.])\d{1,4}','ig');
str = ('abc18.Dat wy.03/12/2019FFF*Dato dost2009/03/03**data wy2020-09-30')
result = str.match(reg).toString()
Received result: 'Dat wy.03/12/2019FFF*Dato dost2009/03/03**data wy2020-09-30'
Expected result: 'Dat wy.03/12/2019,data wy2020-09-30' or preferably: '03/12/2019,2020-09-30'
谢谢。
几个问题。
- 您想在子字符串和日期之间匹配尽可能少的内容,但您当前的正则表达式使用 greed
.{0,}
(same like .*
). See this Question 并改用 .*?
。
dat.*?wy.*?FOO
仍然可以跳过任何其他 dat
。为避免跳过,请使用某些人所说的 Tempered Greedy Token。 .*?
变为 (?:(?!dat).)*?
表示不跳过。
- 这不是真正的问题,但你可以 capture the date separator and reuse 它。
如果只想提取日期部分,也可以使用捕获组。我放了一个demo at regex101.
dat(?:(?!dat).)*?wy.*?(\d{1,4}([/ .-])\d{1,2}\d{1,4})
有很多方法可以达到您想要的结果。另一个想法,我会想到 - 如果你知道,日期之间永远不会出现任何数字,use \D
for non-digit instead of the .
dat\D*?wy\D*(\d{1,4}([/ .-])\d{1,2}\d{1,4})
您可以使用带有反向引用的捕获组来确保 -
和 /
等分隔符在匹配日期中相同。
\bdat\w*\s*wy\.?(\d{4}([-/ .])\d{2}\d{2}|\d{2}([-/ .])\d{2}\d{4})
\bdat\w*\s*wy\.?
单词边界,匹配 dat
后跟 0+ 个单词字符和 0+ 个空白字符。然后匹配 wy
和一个可选的 .
(
捕获 组 1
\d{4}([-/ .])\d{2}\d{2}
匹配以年份开头的类似日期的格式,其中 </code> 是对组 2</li> 中捕获内容的反向引用
<li><code>|
或
\d{2}([-/ .])\d{2}\d{4}
匹配以年份结尾的类似日期的格式,其中 </code> 是对组 3</li> 中捕获内容的反向引用
</ul>
</li>
<li><code>)
关闭群组
该值在捕获组 1 中
注意您可以使日期more specific指定年月日的范围。
我有一个包含多个日期的单行字符串。在 JScript Regex 中,我需要提取按给定顺序由“dat”和“wy”的不区分大小写的子字符串处理的日期。子字符串之前和之后可以是任何字符(新行除外)。
reg = new RegExp('dat.{0,}wy.{0,}\d{1,4}([\-/ \.])\d{1,2}([\-/ \.])\d{1,4}','ig');
str = ('abc18.Dat wy.03/12/2019FFF*Dato dost2009/03/03**data wy2020-09-30')
result = str.match(reg).toString()
Received result: 'Dat wy.03/12/2019FFF*Dato dost2009/03/03**data wy2020-09-30'
Expected result: 'Dat wy.03/12/2019,data wy2020-09-30' or preferably: '03/12/2019,2020-09-30'
谢谢。
几个问题。
- 您想在子字符串和日期之间匹配尽可能少的内容,但您当前的正则表达式使用 greed
.{0,}
(same like.*
). See this Question 并改用.*?
。 dat.*?wy.*?FOO
仍然可以跳过任何其他dat
。为避免跳过,请使用某些人所说的 Tempered Greedy Token。.*?
变为(?:(?!dat).)*?
表示不跳过。- 这不是真正的问题,但你可以 capture the date separator and reuse 它。
如果只想提取日期部分,也可以使用捕获组。我放了一个demo at regex101.
dat(?:(?!dat).)*?wy.*?(\d{1,4}([/ .-])\d{1,2}\d{1,4})
有很多方法可以达到您想要的结果。另一个想法,我会想到 - 如果你知道,日期之间永远不会出现任何数字,use \D
for non-digit instead of the .
dat\D*?wy\D*(\d{1,4}([/ .-])\d{1,2}\d{1,4})
您可以使用带有反向引用的捕获组来确保 -
和 /
等分隔符在匹配日期中相同。
\bdat\w*\s*wy\.?(\d{4}([-/ .])\d{2}\d{2}|\d{2}([-/ .])\d{2}\d{4})
\bdat\w*\s*wy\.?
单词边界,匹配dat
后跟 0+ 个单词字符和 0+ 个空白字符。然后匹配wy
和一个可选的.
(
捕获 组 1\d{4}([-/ .])\d{2}\d{2}
匹配以年份开头的类似日期的格式,其中</code> 是对组 2</li> 中捕获内容的反向引用 <li><code>|
或\d{2}([-/ .])\d{2}\d{4}
匹配以年份结尾的类似日期的格式,其中</code> 是对组 3</li> 中捕获内容的反向引用 </ul> </li> <li><code>)
关闭群组
该值在捕获组 1 中
注意您可以使日期more specific指定年月日的范围。