使用正则表达式从字符串中提取数字和符号

5

我有一个包含文本、数字和符号的字符串。我试图从字符串中提取数字和符号,但效果有限。我只得到了部分数字和符号,而不是整个字符串。为了更清晰、更易于理解,我将解释我的正则表达式。

\d : any number
[+,-,*,/,0-9]+ : 1 or more of any +,-,*,/, or number
\d : any number

代码:

$string = "text 1+1-1*1/1= text";

$regex = "~\d[+,-,*,/,0-9]+\d~siU";
preg_match_all($regex, $string, $matches); 

echo $matches[0][0];

期望结果

1+1-1*1/1

实际结果

1+1

3
相较于你之前的问题,这是一个很大的进步。祝好运! - John Conde
1
把那个东西扔到 https://regex101.com 并查看右上角的框。 - Rizier123
@Rizier123,你看到这个了吗?\d:任何数字 [+,-,,/,0-9] +:1个或多个+, - ,,/或数字 \d:任何数字 - jessica
@jessica 是的,我看到了。现在你可能想把你的正则表达式^^放进去,看看它实际上做了什么。 - Rizier123
它执行了我上面所说的。你在上面粗体字中看到了预期结果和实际结果吗?那就是结果。在regex101中也是一样。 - jessica
@Rizier123 我在问为什么它会这样做,即使我的正则表达式是正确的? - jessica
3个回答

3

去掉U标志。它使得+在匹配时变得非贪婪。此外,在字符列表中,你不需要在字符之间加逗号(如果你想匹配逗号,只需要一个, )。你需要转义-,以免它认为你要创建一个范围。


终于有人找到了问题所在!似乎在上面的正则表达式中,siU是完全不必要的。感谢您指出这一点。 - jessica
@jessica 没问题。它用逗号确实还能工作吗?(以前从未尝试过,也无法从手机测试) - user5051310
不需要了。我已经去掉了逗号,因为逗号是问题的一部分,正如@dxdy所指出的那样。但我认为siU才是问题的主要部分,既然你同时解决了逗号和siU,你的回答是最好的。 - jessica
@Jessica,我告诉过你要去掉“U”标志,但我觉得你完全忽略了“去掉‘U’标志”的建议。 - Sir McPotato
@vinxce 当您说“对于这样的小事情...”时,不清楚U标志是问题所在。请将其编辑到您的答案中并接受赞同。 - user5051310
@Vinxce,既然你忽略了我的评论,我想回敬地忽略你的评论也是理所应当的。 :) - jessica

2
这里的问题在于你的正则表达式混淆了很多未转义的元字符。在你的字符类中,你有 [+,-,*,/,0-9]。你不需要用逗号分隔不同的字符,这只会告诉正则表达式引擎将逗号包含在你的表达式中。此外,你需要转义“-”,因为它在字符类内部具有特殊含义。目前的表达式将被解释为“从“,”到“,”的字符,而不是字面上的“-”字符。斜杠“/”字符也存在类似的问题。表达式\d[+\-*/0-9]+\d应该能够解决问题。

我的眼睛确实误导了我。对此感到抱歉。问题出在其他地方,请查看已编辑的答案。 - dxdy
据我所知,在[]括号内,元字符不需要转义。 - jessica
2
大多数情况下不需要转义,但有些确实需要。其中包括\ ^ ] -。考虑到这一点,引擎又怎么知道0-9是指“从0到9的字符”还是“字符0、-和9”呢? - dxdy
2
很遗憾,语法不是这样工作的。请参考文档中的此页面。它明确指出:“减号(连字符)可以用于在字符类中指定一系列字符。例如,[d-m]匹配d和m之间的任何字母。如果类中需要一个减号字符,则必须使用反斜杠进行转义,或者出现在不能被解释为指示范围的位置上,通常是类中的第一个或最后一个字符。” - dxdy
@jessica 我说过了,你应该把那个正则表达式放进去:https://dev59.com/LY_ea4cB1Zd3GeqPQp1K#bb7mnYgBc1ULPQZFw3zB - Rizier123
显示剩余5条评论

-3

没有用你的代码测试过,但应该可以工作 :)

((?:[0-9]+[\+|\-|\*|\/]?)+)

更详细地说,如果你想了解我的模式: https://regex101.com/r/mF0zO8/2

对于像这样的小字符串,您可以摆脱U标志 :) - Sir McPotato
1
您似乎完全忽略了注释“它不起作用”。 - jessica

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