在一个字符串中查找第一个大写字母的最快方法

10
假设您有这个字符串:hiThere。最快的方法是找到第一个大写字母在哪里?(例如此示例中的 T)。我担心性能问题,因为有些单词很长。

5
你是希望第一个大写字母还是仅仅是第一个大写的"T"? - safarov
1
@HardikPatel:这不是“当然”,从问题中并不清楚。 - Madara's Ghost
我编辑了我的问题,但以防万一,是否有任何大写字母,T只是一个例子。谢谢。 - Martin
9个回答

24

如果只需要匹配一个结果,最简单的方法是使用 preg_match;如果需要匹配所有结果,可以使用 preg_match_all。

http://php.net/manual/en/function.preg-match.php
preg_match_all('/[A-Z]/', $str, $matches, PREG_OFFSET_CAPTURE);

不确定它是否是最快的..


“PREG_OFFSET_CAPTURE” - 这是我试图想到的标志,以获取匹配位置。 - leepowers

7
为了找到第一个大写字母,我会使用 preg_matchPREG_OFFSET_CAPTURE 标志:
$string = "hiThere";

preg_match( '/[A-Z]/', $string, $matches, PREG_OFFSET_CAPTURE );

print_r( $matches[0] );

这将返回以下内容:

Array ( [0] => T [1] => 2 )

您可以将这个逻辑封装成一个函数,反复使用:

function firstUC ( $subject ) {
  $n = preg_match( '/[A-Z]/', $subject, $matches, PREG_OFFSET_CAPTURE );
  return $n ? $matches[0] : false;
}

echo ( $res = firstUC( "upperCase" ) ) ? $res[1] : "Not found" ;
// Returns: 5

echo ( $res = firstUC( "nouppers!" ) ) ? $res[1] : "Not found" ;
// Returns: Not found

6

另一种方法

$stringCamelCase = 'stringCamelCase';// hiThere

使用 preg_split() 的方法:

$array      = preg_split('#([A-Z][^A-Z]*)#', $stringCamelCase, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
echo strlen($array[0]);// $array = ['string', 'Camel', 'Case']

使用 strpbrk() 函数的方法:
$CamelCase = strpbrk($stringCamelCase, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
echo strpos($stringCamelCase, $CamelCase);

2
我想象做这个的方法是:
strlen(preg_replace("/^([a-z]*)[A-Z].*$/", "$1", $str));

isThis => 2
largerWord => 6


很棒,但是我不太明白为什么这能生效。尽管在字符串 $str = 'asas.2tAOPPr'; 上得到了12:/ - Sarfaraaz
我已经弄清楚了。它试图检索第一组全是小写字母的字符。它不考虑数字,但大多数驼峰式字符串中间不会有数字。然后获取这些字符的长度。如果找不到匹配项,则返回整个字符串的长度。 - Sarfaraaz
差不多了。否则你可以运行“/^([^A-Z])[A-Z].$ /”。 - Robin Castlin
我只是将数字添加到第一个括号中,以获得与您原始答案类似的工作方式 ------------------- / ^([a-z\d]*)[A-Z].*$,因为我实际上不想在其中加入句点。 - Sarfaraaz

1

在找到这个数组是多维数组之前,我对这个函数感到很困惑。没有看到任何人的代码提到过这一点。为了获取第一个大写字母的位置,我使用了以下代码:

<?php

$field = "i_select_Interior_Quote";
preg_match( '/[A-Z]/', $field, $m, PREG_OFFSET_CAPTURE );

$posi=$m[0][1];

echo '<br><br>'.$posi; // outputs 9

?>

1
这是一个(或多或少)一行的解决方案。
$pos = strcspn($string, 'ABCDEFGHJIJKLMNOPQRSTUVWXYZ');

strcspn将返回第二个参数中任何字符的第一次出现的位置,如果没有字符出现,则返回字符串的长度。

返回str1中不包含str2中任何字符的初始段的长度。

$pos = strcspn($string, 'ABCDEFGHJIJKLMNOPQRSTUVWXYZ');
if ($pos < strlen($string)) {
    echo "capital letter as index $pos";
}

1
使用 strpos() 函数。
echo strpos($string, "T");

他想要通用代码,而不是特定于那个代码的代码。比如说,当他想从字符串“abcXyz”中获取“X”时,你的代码会失败。 - Umakant Patil
@UmakantPatil:自从我写这个答案以来,问题已经被编辑了三次。它的意义发生了很大的改变。如果您在对一个非常古老的答案进行投票时能够重新审查修订,我会非常感激。 - Madara's Ghost
抱歉,我本来想取消投票,但由于显示“您的投票已锁定”,无法进行操作。 - Umakant Patil
1
@UmakantPatil:没关系,我回家后会删除这个答案,因为它已经不再适用了。谢谢 :) - Madara's Ghost

0

解决方案适用于a-z字符。可能不支持Unicode。

 preg_match('/[A-Z]/', $str, $m);
 if(isset($m[1])) {
    echo 'First upper char is '.$m[1].' and located at '. strpos($string, "T");
 }
 else {
    'There is no upperchar';
 }

0

我在自己的应用程序中使用了什么:

function acronyms($s){
  $s=str_replace(array('& ','of ','the ','and '),'',strtolower($s));
  $s=ucwords(trim($s)); //Collecting data
  if(strlen($s)>0 && preg_match_all('/[A-Z]/',$s,$m))   return implode('',$m[0]);
return $s;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接