如何获取连字符和尾随子字符串两侧的子字符串?
How to get substrings on both sides of hyphen and trailing substring?
我目前正在开发一个使用特定字符串调用函数的网络应用程序。这是一个示例字符串:
$string = "translate from-to word for translate"
首先我需要验证字符串,它应该像上面的那样$string
。我应该如何验证字符串?
然后我需要从$string
中提取3个子串。
- 连字符前面的单词。 (待定名:
$target
)
- 连字符后面的单词。 (待定名:
$source
)
$source
之后到字符串末尾的文本(不包括第一个 space)。 (待定名:$translate
)
这是我尝试获取 from
和 to
:
的编码尝试
$found = false;
$source ="";
$target = "";
$next = 3;
$prev = 1;
for($i=0;$i<strlen($string);$i++){
if($found== false){
if($string[$i] == "-"){
$found = true;
while($string[$i+$prev] != " "){
$target .= $string[$i+$prev];
$prev +=1;
}
/*$next -=1;
while($string[$i-$next] != " " && $next > 0){
$source .= $string[$i-$next];
$next -=1;
}*/
}
}
}
从那个代码,我只能return-
之后包含to
的$target
。
我不知道如何得到$source
.
请告诉我获得 from
作为 $source
和 to
作为 $target
的最快方法。
然后我需要得到word for translate
(from-to
之后的所有字符串)。
所以结果应该是
$target = "to";
$source = "from";
$translate = "word for translate";
最后,如果 $string
有两个连字符,比如 translate from-to from-to test-test word for translate
,它应该是 return false
;
注意 to
和from
是随机字符串。
如果我理解正确你的问题,这可以用 regular expression:
<?php
$string = "translate from-to word for translate";
$result = preg_match("/^([\w ]+?) (\w+)-(\w+) ([\w ]+)$/", $string, $matches);
if ($result) {
print_r($matches);
$source = $matches[2];
$target = $matches[3];
$translate = $matches[4];
} else {
echo "No match";
}
输出:
Array
(
[0] => translate from-to word for translate
[1] => translate
[2] => from
[3] => to
[4] => word for translate
)
考虑以下可能的输入字符串:
translate from-to word for translate
(1 个连字符,无重音符号或非英语字符)
translate dari-ke dari-ke word for translate
(2 个连字符)
translate clé-solution word for translate
(1 个连字符,使用重音字符)
translate goodbye-さようなら word for translate
(1 个连字符,使用日文字符)
像这样的不区分大小写的模式:/^[a-z]+? ([a-z]+)-([a-z]+?) ([a-z ]+)$/i
将按照要求高效地执行前两个示例字符串,但不会执行后两个。
使用 "word character" (\w
) 匹配子字符串(而不是不区分大小写的 [a-z]
)将按预期执行前两个样本,但也允许 0-9
和 _
作为有效字符。这意味着模式准确性略有下降(这可能对您的项目没有明显影响)。
如果您要翻译的字符串可能超出英文字符范围,使用 "negated character class" 进行匹配会更简单/更宽容。如果你想允许 a-z
以外的字母,如重音字符和其他多字节字符,那么 [^-]
将提供广泛的字符允许(以允许许多不需要的字母为代价)。这里是 a demo of this kind of pattern.
重要的是只为您要随后使用的子字符串编写 "capture groups"。因此,我没有捕获前导子字符串 translate
.
list()
是一个方便的 "language construct" 来为数组值分配变量名。请注意,第一个元素(全字符串匹配)未分配给变量。这就是为什么list()
的参数以,
开头的原因。如果您不想利用 list()
的便利性,那么您可以像这样在三行中手动分配三个变量名称:
$source=$out[1];
$target=$out[2];
$translate=$out[3];
代码:(Demo)
$strings=[
"translate from-to word for translate",
"translate dari-ke dari-ke word for translate",
"translate clé-solution word for translate",
"translate goodbye-さようなら word for translate"
];
foreach($strings as $string){
if(preg_match('/^[a-z]+? ([^-]+)-([^-]+?) ([a-z ]+)$/i',$string,$out)){
list(,$source,$target,$translate)=$out;
echo "source=$source; target=$target; translate=$translate";
}else{
var_export(false); // $found=false;
}
echo "<br>";
}
输出:
source=from; target=to; translate=word for translate
false
source=clé; target=solution; translate=word for translate
source=goodbye; target=さようなら; translate=word for translate
虽然正则表达式提供了一种函数调用更少的更简洁的方法,但这是一种非正则表达式方法:
if(substr_count($string,'-')!=1){
var_export(false); // $found=false;
}else{
$trimmed=ltrim($string,'translate ');
$array=explode(' ',$trimmed,2);
list($source,$target)=explode('-',$array[0]);
$translate=$array[1];
echo "source=$source; target=$target; translate=$translate";
}
我目前正在开发一个使用特定字符串调用函数的网络应用程序。这是一个示例字符串:
$string = "translate from-to word for translate"
首先我需要验证字符串,它应该像上面的那样$string
。我应该如何验证字符串?
然后我需要从$string
中提取3个子串。
- 连字符前面的单词。 (待定名:
$target
) - 连字符后面的单词。 (待定名:
$source
) $source
之后到字符串末尾的文本(不包括第一个 space)。 (待定名:$translate
)
这是我尝试获取 from
和 to
:
$found = false;
$source ="";
$target = "";
$next = 3;
$prev = 1;
for($i=0;$i<strlen($string);$i++){
if($found== false){
if($string[$i] == "-"){
$found = true;
while($string[$i+$prev] != " "){
$target .= $string[$i+$prev];
$prev +=1;
}
/*$next -=1;
while($string[$i-$next] != " " && $next > 0){
$source .= $string[$i-$next];
$next -=1;
}*/
}
}
}
从那个代码,我只能return-
之后包含to
的$target
。
我不知道如何得到$source
.
请告诉我获得 from
作为 $source
和 to
作为 $target
的最快方法。
然后我需要得到word for translate
(from-to
之后的所有字符串)。
所以结果应该是
$target = "to";
$source = "from";
$translate = "word for translate";
最后,如果 $string
有两个连字符,比如 translate from-to from-to test-test word for translate
,它应该是 return false
;
注意 to
和from
是随机字符串。
如果我理解正确你的问题,这可以用 regular expression:
<?php
$string = "translate from-to word for translate";
$result = preg_match("/^([\w ]+?) (\w+)-(\w+) ([\w ]+)$/", $string, $matches);
if ($result) {
print_r($matches);
$source = $matches[2];
$target = $matches[3];
$translate = $matches[4];
} else {
echo "No match";
}
输出:
Array
(
[0] => translate from-to word for translate
[1] => translate
[2] => from
[3] => to
[4] => word for translate
)
考虑以下可能的输入字符串:
translate from-to word for translate
(1 个连字符,无重音符号或非英语字符)translate dari-ke dari-ke word for translate
(2 个连字符)translate clé-solution word for translate
(1 个连字符,使用重音字符)translate goodbye-さようなら word for translate
(1 个连字符,使用日文字符)
像这样的不区分大小写的模式:/^[a-z]+? ([a-z]+)-([a-z]+?) ([a-z ]+)$/i
将按照要求高效地执行前两个示例字符串,但不会执行后两个。
使用 "word character" (\w
) 匹配子字符串(而不是不区分大小写的 [a-z]
)将按预期执行前两个样本,但也允许 0-9
和 _
作为有效字符。这意味着模式准确性略有下降(这可能对您的项目没有明显影响)。
如果您要翻译的字符串可能超出英文字符范围,使用 "negated character class" 进行匹配会更简单/更宽容。如果你想允许 a-z
以外的字母,如重音字符和其他多字节字符,那么 [^-]
将提供广泛的字符允许(以允许许多不需要的字母为代价)。这里是 a demo of this kind of pattern.
重要的是只为您要随后使用的子字符串编写 "capture groups"。因此,我没有捕获前导子字符串 translate
.
list()
是一个方便的 "language construct" 来为数组值分配变量名。请注意,第一个元素(全字符串匹配)未分配给变量。这就是为什么list()
的参数以,
开头的原因。如果您不想利用 list()
的便利性,那么您可以像这样在三行中手动分配三个变量名称:
$source=$out[1];
$target=$out[2];
$translate=$out[3];
代码:(Demo)
$strings=[
"translate from-to word for translate",
"translate dari-ke dari-ke word for translate",
"translate clé-solution word for translate",
"translate goodbye-さようなら word for translate"
];
foreach($strings as $string){
if(preg_match('/^[a-z]+? ([^-]+)-([^-]+?) ([a-z ]+)$/i',$string,$out)){
list(,$source,$target,$translate)=$out;
echo "source=$source; target=$target; translate=$translate";
}else{
var_export(false); // $found=false;
}
echo "<br>";
}
输出:
source=from; target=to; translate=word for translate
false
source=clé; target=solution; translate=word for translate
source=goodbye; target=さようなら; translate=word for translate
虽然正则表达式提供了一种函数调用更少的更简洁的方法,但这是一种非正则表达式方法:
if(substr_count($string,'-')!=1){
var_export(false); // $found=false;
}else{
$trimmed=ltrim($string,'translate ');
$array=explode(' ',$trimmed,2);
list($source,$target)=explode('-',$array[0]);
$translate=$array[1];
echo "source=$source; target=$target; translate=$translate";
}