我有一个正则表达式尝试按专业划分问题。说我有以下正则表达式:
(?P<speciality>[0-9x]+)
这个问题很好(正确匹配:7)
(7)以下哪项至少被视为食管癌的危险因素?
为此(正确匹配:8和13)
(8,13)30岁女性闭经,血清雌激素水平低,血清LH / FSH高,最可能诊断为:
但不是这个(不正确的匹配:20)。
妊娠早期自然流产(20周前)最常见的原因是:
我只需要问题开头的括号中的数字,所有其他括号都应该被忽略。单独使用正则表达式是否可能(前瞻?)。
答案 0 :(得分:3)
如果您的正则表达式支持\G
continuous matching和\K
reset beginning of match,请尝试:
(?:^\(|\G,)\K[\dx]+
在最后一次匹配后, ^\(
会在开始|
或\G
匹配,
时匹配括号。然后\K
重置+
[\dx]
中的一个或多个\d
。 ([0-9]
是$0
的{{3}}。匹配将在$str = "(1x,2,3x) abc (1,2x,3) d";
preg_match_all('~(?:^\(|\G,)\K[\dx]+~', $str, $out);
。
shorthand; Test at regex101.com
PHP示例
Array
(
[0] => 1x
[1] => 2
[2] => 3x
)
的print_r($ OUT [0]);
{{1}}
答案 1 :(得分:1)
也许这样的东西会起作用(你没有提到你正在使用的正则表达式,虽然我猜测它是使用命名组的PCRE - 是的,它确实使用正向前瞻):< / p>
^\((?P<speciality>(?:[0-9x]+,?)+)(?=\))/mg
插入符号^
与多行修饰符\m
相结合(导致锚点^
和$
分别匹配行的开头和结尾,而不是字符串的开头和结尾)将确保匹配的内容位于段落的开头。专业将在specialty
命名的捕获组中捕获;唯一需要注意的是,如果给出了多个专业(如示例中的(8,13)
),则捕获将是逗号分隔的列表,就像专业是逗号分隔列表一样(使用相同的示例) ,在这种情况下,捕获将是8,13
。
答案 2 :(得分:1)
(?P<speciality>[0-9x]+)
匹配输入中任何位置的任何非空数字序列。括号只是界定捕获组,但不属于匹配。
匹配行开头的括号之间的数字(或逗号分隔),你可以使用这样的东西
^\((\d+)(,(\d+))*\)
编辑
似乎重复捕获组,如in (,(\d+))*
,只返回最后一场比赛。所以为了得到这些值,必须抓住完整的数字列表并在之后解析它:
^\((?P<specialities>(\d+)(,(\d+))*)\)
将在括号之间用逗号分隔一个或多个数字。
添加了行锚的开头,因此它位于行的开头。