rin*_*t.6 8 php regex string backreference camelcasing
我第一次在正则表达式中使用捕获组,我想知道我的问题是什么,因为我假设正则表达式引擎从左到右查看字符串.
我正在尝试将UpperCamelCase字符串转换为hyphened-lowercase-string,例如:
HelloWorldThisIsATest => hello-world-this-is-a-test
Run Code Online (Sandbox Code Playgroud)
我的前提条件是字母字符串,所以我不需要担心数字或其他字符.这是我尝试过的:
mb_strtolower(preg_replace('/([A-Za-z])([A-Z])/', '$1-$2', "HelloWorldThisIsATest"));
Run Code Online (Sandbox Code Playgroud)
结果:
hello-world-this-is-atest
Run Code Online (Sandbox Code Playgroud)
这几乎是我想要的,除了a和之间应该有一个连字符test.我已经包含A-Z在我的第一个捕获组中,所以我会假设引擎看到AT并连接了那个.
我究竟做错了什么?
你的正则表达式不起作用的原因:重叠匹配
sA的IsATest,可以让你插入-之间s和A-在A和之间插入T,正则表达式必须匹配AT.A它已经作为一部分匹配sA.您不能在直接正则表达式中重叠匹配.用两条简单的线条做
这是使用正则表达式执行此操作的简单方法:
$regex = '~(?<=[a-zA-Z])(?=[A-Z])~';
echo strtolower(preg_replace($regex,"-","HelloWorldThisIsATest"));
Run Code Online (Sandbox Code Playgroud)
请参阅php演示文稿底部的输出:
输出:
hello-world-this-is-a-test
马上就会添加解释.:)
(?<=[a-zA-Z])回顾后发断言,什么先于当前位置是信(?=[A-Z])预测先行断言,接下来的当前位置是一个大写字母.-,并将批次转换为小写.如果仔细查看此regex101屏幕,可以看到正则表达式匹配的单词之间的线条.
参考
为简单起见,我将两个正则表达式分开:
preg_replace(array('/([a-z])([A-Z])/', '/([A-Z]+)([A-Z])/'), '$1-$2', $string);
Run Code Online (Sandbox Code Playgroud)
它处理字符串两次以查找:
这将有以下行为:
ThisIsHTMLTest -> This-Is-HTML-Test
ThisIsATest -> This-Is-A-Test
Run Code Online (Sandbox Code Playgroud)
或者,使用前瞻断言(这将影响上一次匹配中使用的最后一个大写字母的重用):
preg_replace('/([A-Z]+|[a-z]+)(?=[A-Z])/', '$1-', $string);
Run Code Online (Sandbox Code Playgroud)