Sublime Text片段将camelCase转换为snake_case

时间:2018-12-22 19:20:01

标签: php regex perl sublimetext3 code-snippets

嗨,我正在尝试制作一个精彩的文本片段,我想 将camelCase单词转换为snake_case。我确实知道有一些插件可以让您将字符串转换为snake_case,但我想通过出色的文本片段来实现。

我有一个如下的片段。

<snippet>
    <content><![CDATA[
/**
 * ${TM_FILEPATH/^.+\/(\w+)\.php$/${1}/} belongs to many (many-to-many) ${1/^((.+)ies)|(.+[^s])s$/\u(?1$2y:$3)/}.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function $1()
{
    return \$this->belongsToMany('App\\${1/^((.+)ies)|(.+[^s])s$/\u(?1$2y:$3)/}', '${TM_FILEPATH/^.+\/(\w+)\.php$/\l${1}/}_$1', '${TM_FILEPATH/^.+\/(\w+)\.php$/\l${1}/}_id', '${1/^((.+)ies)|(.+[^s])s$/\l(?1$2y:$3)/}_id');
}
]]></content>
    <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
    <tabTrigger>btm</tabTrigger>
    <!-- Optional: Set a scope to limit where the snippet will trigger -->
    <scope>source.php</scope>
    <description>Eloquent belongsToMany() (pivot) relation</description>
</snippet>

作为输出,它给了我。

 /**
     * UserMessages belongs to many (many-to-many) Role.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles()
    {
        return $this->belongsToMany('App\Role', 'userMessages_roles', 'userMessages_id', 'role_id');
    }

我要结束的是将userMessages作为user_messages。 任何想法如何做到这一点。

非常感谢。

2 个答案:

答案 0 :(得分:6)

基于您的示例,以下是一个类似示例的代码段示例,但为了清楚起见而进行了缩短(我也将范围更改为embedding.php,因此它将触发我用于PHP的语法)。您应该能够在较大的代码段示例中对此进行调整。

<snippet>
    <content><![CDATA[
// ${1/^([A-Z])|(?:([A-Z]))/(?1\l$1:)(?2_\l$2:)/g}
public function ${1}()
{
    $0
}
]]></content>
    <tabTrigger>btm</tabTrigger>
    <scope>embedding.php</scope>
    <description>Eloquent belongsToMany() (pivot) relation</description>
</snippet>

Example of snippet in use

其基础可以在snippetsunofficial documentation页中看到。摘要中变量的扩展形式为${variable/regex/format_string/options}。正则表达式使用boost library regular expressionsformat strings

Boost支持以(?Ntrue:false)的形式进行条件替换,对于捕获组N,如果匹配项捕获了某些内容,则替换文本为true,否则为false

在这里,我们在正则表达式中使用替代项以具有两个捕获组,因此我们可以根据匹配的项提供两个不同的替换项。第一个捕获组捕获前导大写字符,并将其转换为小写,而第二个捕获组(未锚定到行的开头)执行相同操作,并且在匹配之前带有下划线。

答案 1 :(得分:2)

Perl提供了\L修饰符,可以在替换时小写捕获。 捕获在方括号()中,并可以由$ 1,$ 2等进行反向引用。

因此,所需要做的就是先找到一个小写字符,再找到一个大写字符,然后再将其转换为小写。

sub camel_case_to_underscore {
    my $method_name = shift;   
    $method_name =~s /([a-z])([A-Z])/$1_\L$2/g;
    return lcfirst $method_name;
}

g标志全局替换,因此字符串中的所有匹配项。

请注意,此函数还将小写字符串的第一个字母, 我想这就是您想要的。