RegEx环视问题

时间:2013-03-05 14:12:48

标签: regex powershell-v2.0

我正在使用Powershell 2.0。我有像my_file_name_01012013_111546.xls这样的文件名。我想获得my_file_name.xls。我试过了:

  

.*(?=_.{8}_.{6})

返回my_file_name。但是,当我尝试

  

.*(?=_.{8}_.{6}).{3}

返回my_file_name_01

我无法弄清楚如何获得扩展名(可以是任意3个字符。时间/日期部分将始终为_8个字符_6个字符。

我看了很多例子并试了很多东西,但没有运气。

4 个答案:

答案 0 :(得分:1)

如果您只想查找名称和扩展程序,可能需要以下内容:^(.*)_[0-9]{8}_[0-9]{6}(\..{3})$

my_file_name将在反向引用1和.xls的反向引用2中。

如果你想删除其他所有内容并返回答案,你想要用“{”代替“数字”:'my_file_name_01012013_111546.xls' -replace '_[0-9]{8}_[0-9]{6}' ''。你不能简单地将字符串的两位(名称和扩展名)拉出作为一个匹配 - 正则表达式模式只匹配连续的块。

答案 1 :(得分:0)

您指定的原始正则表达式返回后面有14个字符的最大匹配项(您可以更改为(?=。{14})相同)。

一旦你改变它,它将返回最大匹配,其后有14个字符+接下来的3个字符。这就是你得到这个结果的原因。

如果您可以使用反向引用,Inductiveload描述的方法可能会更好。我使用以下正则表达式:(.*)[_\d]{16}\.(.*)否则,我会分两个阶段进行

  1. 获取初始部分
  2. 获取扩展程序

答案 2 :(得分:0)

试试这个(未经测试),但它适用于任何'my_file_name'长度,任何长度的数字和任何类型的扩展。

"my_file_name_01012013_111546.xls" -replace '(?<=[\D_]*)(_[\d_]*)(\..*)','$2'

非正则表达式解决方案:

$a = "my_file_name_01012013_111546.xls"

$a.replace( ($a.substring( ($a.LastIndexOf('.') - 16 ) , 16 )),"") 

答案 3 :(得分:0)

添加my_filename_01时获得.*(?=_.{8}_.{6})的原因是因为lookaheads为零宽度。这意味着它们不会消耗字符串中的字符。

如您所述,my_file_name_.{8}_.{6}匹配,因为该字符串后跟匹配my_file_name的内容,但是一旦找到该匹配项,您只会使用.{3} ,因此添加_01将消耗接下来的3个字符,即{{1}}。

至于适合您需求的正则表达式,其他人已经发布了可行的替代方案。