我正在尝试创建一个VS代码片段,该代码片段基于项目中的当前文件夹构建名称空间。
由TM_DIRECTORY
变量提供的当前路径可能是这样的。/Users/bernhardrichter/GitHub/heatkeeper2000/src/HeatKeeper.Server/Mapping
我希望最终得到的是namespace HeatKeeper.Server.Mapping
,因为我的根源文件夹是src
所以我需要去掉之前的所有东西,包括src
,这样我们就剩下HeatKeeper.Server/Mapping
了。然后我需要将/
替换(转换)为.
,以便最终结果为HeatKeeper.Server.Mapping
。
有没有可能在一次转换中做到这一点?如果没有,是否可以有多个转换?
这是我目前所拥有的"namespace ${TM_DIRECTORY/(.*src.)(.*).*$/$2/}"
这输出namespace HeatKeeper.Server/Mapping
这几乎是我想要的。我只需要将所有/
替换为.
问题是我不知道把这个转换放在哪里。
转换看起来像这样。"${TM_DIRECTORY/[\\/]/./g}"
这给了我.Users.bernhardrichter.GitHub.heatkeeper2000.src.HeatKeeper.Server.Mapping
我就是不知道怎么把这两个合并结合起来?
2条答案
按热度按时间prdp8dxp1#
请在编辑后查看更一般的答案(不仅仅是最后两个目录)。
原文回答:
是的,你可以在一个片段中完成它们,你只需要分别捕获
src
之后的两个目录。试试看:然后在两个捕获组之间放置
period
。这个正则表达式假设您总是在所需的两个目录之前有一个src
目录。如果不是这样,这将捕获最后两个目录:注意路径分隔符“
/
“必须是双转义的。**编辑-----------------------------------------------
对于更一般的情况,即在特定目录之后有未知数量的目录,请尝试以下形式:
在出现
src
的地方,放入最后一个你不需要的目录。这适用于src
之后的一个或多个目录(在本例中)。有趣的是,这是一个文件夹的情况下,是最棘手的。这是通过额外的条件
${3:+.}
解决的,这意味着如果有捕获组3,则插入.
。有关正则表达式的解释,请参见reg101 demo。在该链接中,您可以看到除了
one folder case
之外,还有一个更简单的替换。如果你不介意在最后一个.
上回退,你可以用$2.$5
代替我上面使用的$2${3:+.}${5:+.}$5
。最后,请注意,上面的设计是为了使用正斜杠
/
路径分隔符。要修改它以使用反斜杠/正斜杠分隔符,请查看以下内容(将USERS
作为最后一个不需要的目录):所有的正斜杠
\\/
都被转换为正斜杠和反斜杠[\\/\\\\]
,如果你想测试文本\
,反斜杠必须显示为\\\\
。哟。[For原来的问题,只需要在开头加上
namespace
。krugob8w2#
可悲的是@Marks解决方案并没有真正为我工作,它仍然包含驱动器和所有文件夹,直到文件名,或者如果我使用新的
${RELATIVE_FILEPATH}
,它仍然包含文件名(我想要没有工作区文件夹的完整路径,所以基本上是一个c#项目中的项目路径-例如)幸运的是,使用新的相对文件路径变量,我们可以消除替换和捕获组周围的一些复杂性($3
,$5
等)和RegEx本身。在first answer和an other post from @Mark上修修补补,我得出了以下解决方案:
(for一点测试见regex101.com不是100%准确的VSCode似乎是如何做到这一点,但哦,好吧)
。我知道这看起来还是有点糟糕,但是让我把它简化一点,分解一下
首先,为了简单起见,我们不使用
\
和/
作为分隔符,而是使用#
,并删除了代码片段所需的双转义。我们的目标是:^([^#]+)#|([^#]+)#|(?:[^#]+\.[^#]+)
$1${2:+.}$2
此外,我们可以将RegEx分解为3个替代方案
|
:^([^#]+)#
([^#]+)#
(?:[^#]+\.[^#]+)
看看第一个和第二个有多相似这是因为,在本质上,两者都捕获了我们的文件夹部分,但第一个查找的是第一个文件夹
^([^#]+)#
查找字符串的开头(^
),然后在捕获组(( )
)中查找一个以上的非#
符号([^#]+
),后面紧跟一个#
=>,这样我们就得到了捕获组$1
中没有任何#
的第一个文件夹([^#]+)#
完全相同,但去掉了字符串开头部分=>这里找到的所有内容都落在捕获组$2
中,但去掉了分隔符#
(?:[^#]+\.[^#]+)
具有非捕获捕获组((?: ... )
),它查找多个非#
符号([^#]+
)后面正好是一个.
(\.
)后再接一个以上的非#
符号([^#]+
)=>这样我们就可以捕获文件名及其扩展名,甚至允许文件名中有额外的.
,然后将其丢弃最后,我们使用transform的格式部分(见这里)将我们的输出拼接在一起:
$1
),按原样写入${2:+.}
)(每次匹配该组时重复)$2
)(每次匹配组时重复)有了这个,我们没有一个点(或多个)在年底,删除文件名与扩展名(无论有多少
.
它包含),并取代所有#
(或在原来的情况下,任何\
或/
)与.
我想我在空闲时间花了>24小时的时间来做这个(我讨厌RegEx),我能把它们花在写代码上吗?当然,但有时候追随你的完美主义和迎接挑战也会很有趣;)