3 回答

TA贡献1875条经验 获得超3个赞
我有点失望,因为我没有足够的详细信息让您一路进入查询过程,所以我只会改变您的元素值。
建立分组字符串——Genus 变量。在进入循环之前将其设置为 null
迭代时,通过提取第一个词确定当前行是否为属值,然后检查它是否仅由大写字母组成。
如果是,将其缓存为新的分组值并将其存储到输出数组
如果不是,则将格式化的“属种”字符串推入结果数组
我喜欢正则表达式,但由于您的数据已经拆分为元素,因此使用正则表达式执行此任务没有任何好处。
代码:(演示)
$result = [];
$currentGenus = null;
foreach ($array as $line) {
$firstWord = strstr($line, ' ', true);
if (ctype_upper($firstWord)) {
$currentGenus = $firstWord;
$result[] = $firstWord;
} else {
$result[] = ucfirst(strtolower($currentGenus)) . ' ' . explode(' ', $line, 3)[1];
}
}
var_export($result);
输出:
array (
0 => 'ACHNANTHES',
1 => 'Achnanthes brevipes',
2 => 'Achnanthes coarctata',
3 => 'Achnanthes cocconeiformis',
4 => 'Achnanthes gibberula',
5 => 'Achnanthes lacunarum',
6 => 'Achnanthes lineariformis',
7 => 'Achnanthes longipes',
8 => 'Achnanthes nollii',
9 => 'Achnanthes parvula',
10 => 'Achnanthes petersenii',
11 => 'Achnanthes pyrenaicum',
12 => 'Achnanthes stolida',
13 => 'Achnanthes thermalis',
14 => 'Achnanthes trinodis',
15 => 'Achnanthes wellsiae',
16 => 'PLATESSA',
17 => 'Platessa conspicua',
18 => 'Platessa montana',
19 => 'Platessa salinarum',
20 => 'ACHNANTHIDIUM',
21 => 'Achnanthidium affine',
22 => 'Achnanthidium deflexum',
23 => 'Achnanthidium exiguum',
24 => 'Achnanthidium exile',
25 => 'Achnanthidium lanceolatum',
26 => 'Achnanthidium minutissimum',
27 => 'Achnanthidium minutum',
28 => 'Achnanthidium thermale',
29 => 'EUCOCCONEIS',
30 => 'Eucocconeis flexella',
31 => 'Eucocconeis laevis',
32 => 'Eucocconeis quadratarea',
)

TA贡献1810条经验 获得超4个赞
我很高兴被证明是错误的,但我认为使用简单替换的 PCRE 正则表达式引擎无法获得所需的结果。
假设字符串是
ACHNANTHES
A. brevipes
A. coarctata
A. cocconeiformis
PLATESSA
P. conspicua
P. montana
P. salinarum
如果你颠倒线条以获得
P. salinarum
P. montana
P. conspicua
PLATESSA
A. cocconeiformis
A. coarctata
A. brevipes
ACHNANTHES
你可以使用正则表达式
^[A-Z]\.(?=\s+[a-z]+\s*(?:[A-Z]\.\s+[a-z]+\s*)*([A-Z]+)\s*$)
获取匹配项并将每个匹配项替换为捕获组的内容,以获得
PLATESSA salinarum
PLATESSA montana
PLATESSA conspicua
PLATESSA
ACHNANTHES cocconeiformis
ACHNANTHES coarctata
ACHNANTHES brevipes
ACHNANTHES
此时通过反转这些行获得所需的结果:
ACHNANTHES
ACHNANTHES brevipes
ACHNANTHES coarctata
ACHNANTHES cocconeiformis
PLATESSA
PLATESSA conspicua
PLATESSA montana
PLATESSA salinarum
演示
以下操作由 PHP 的正则表达式引擎 PCRE 执行。
^ # match beginning of line
[A-Z]\. # match uc ltr then '.'
(?= # begin non-cap grp
\s+[a-z]+\s* # match 1+ whtspaces, 1+ lc ltrs, 0+ whtspaces
(?: # begin non-cap grp
[A-Z]\. # match line begin with uc ltr then '.'
\s+[a-z]+\s* # match 1+ whtspaces, 1+ lc ltrs, 0+ whtspaces
) # end non-cap grp
* # execute non-cap grp 0+ times
([A-Z]+) # match 1+ uc ltrs in cap grp 1
\s* # match 0+ whtspaces
$ # match end of line
) # end positive lookahead

TA贡献1820条经验 获得超10个赞
为了解决您的问题,我会先考虑您将使用哪种逻辑,然后再考虑任何 PHP 语言细节。大多数通用编程语言(例如 PHP)可以完成您在字符串操作方面所需的大部分工作,因此现在不必担心您将如何实现您的逻辑。
我认为在这种情况下使用正则表达式库会有点矫枉过正。有很多方法可以解决您的问题,而且通常有一个比我首先想到的更好的方法,但我将复习一下我首先想到的逻辑。
首先,我将回顾一些重要的假设。这意味着属行仅包含字母,而种行将以字母开头,然后是点。我还假设了三个新事物:
除了属行和种行之外,没有其他类型的行
属行至少有两个字符长
第一行是属名。
所有这些假设都应该是真实的,如果它们是真实的,那么这个解决方案就会起作用。这是我的英语逻辑:
Declare a variable that will be a string that keeps track of your current genus name
For each line (AKA for each string in your array), do this chunk of code:
See if the second letter of the current line is not a dot
If it is not, this line is your current genus name: change
your current genus name variable to the current line
BUT... if the second letter of the current line IS a dot
This is a species line, and we will need to transform it, and to do that...
Make a new string that is the current line with the first two characters cut off
Make a new string copy of your current genus name, but where it just
starts with a capital instead of being all-caps
Make a new string, which is those two strings you just made put together
Replace the current line with that newest string you just made
现在,我不会给你一个彻底的解决方案,因为如果我剥夺你这个学习机会,Stack Overflow 会恨我,但我会让你知道一些有用的语法来解决这个问题。
foreach 循环 https://www.w3schools.in/php/looping/foreach/
字符串 https://www.php.net/language.types.string(搜索“按字符访问和修改字符串”)
if 和 else 语句 https://www.w3schools.com/php/php_if_else.asp
子串 https://www.php.net/manual/en/function.substr.php
有用的字符串大小写函数 https://www.javatpoint.com/php-string-strtolower-function
字符串连接 https://www.php.net/manual/en/language.operators.string.php
PS - 一个真正好的解决方案将有错误处理,比如如果属名只有一个字符长,或者只有返回字符的行,等等,但是为了简单起见,我没有'在此解决方案中不要这样做。这个答案应该适合您的目的,请记住,错误处理是一种很好的做法,并且会为您省去很多麻烦。
- 3 回答
- 0 关注
- 108 浏览
添加回答
举报