我怎么能拆掉一根绳子?

时间:2016-05-20 22:19:10

标签: php regex string

我有这样的模式:

[X number of digits][c][32 characters (md5)][X]

/* Examples:
2 c jg3j2kf290e8ghnaje48grlrpas0942g 65
5 c kdjeuw84398fj02i397hf4343i013g44 94824
1 c pokdk94jf0934nf0932mf3923249f3j3 3
*/

注意:真实字符串中不存在这些示例中的空格。

我需要将这样一个字符串分为四个部分:

// based on first example
$the_number_of_digits = 2
$separator            = c // this is constant
$hashed_string        = jg3j2kf290e8ghnaje48grlrpas0942g
$number               = 65

我该怎么做?

这是我到目前为止所尝试的内容:

/^(\d+)(c)(\w{32})/

Online Demo

我的模式无法获得最后一部分。

编辑:我不想选择其余的号码作为最后一部分。我需要一个基于该字符串开头的数字的算法。

因为我的字符串可能是这样的:

2 c 65 jg3j2kf290e8ghnaje48grlrpas0942g

4 个答案:

答案 0 :(得分:4)

此正则表达式使用命名组来访问结果:

(?<numDigits>\d+) (?<separator>c) (?<hashedString>\w{32}) (?<number>\d+)

编辑 :(来自@ RocketHazmat的有用评论)因为OP想要验证“数字”具有“numDigits”中的数字位数:

  

使用提供的正则表达式然后验证PHP中的数字长度。如果(   strlen($ matches ['number'])== $ matches ['numDigits'])

regex demo输出(您的字符串作为输入):

enter image description here

答案 1 :(得分:2)

一个匹配驱动另一个匹配的长度的事实表明你需要比单个表达更复杂的东西。但是,它不需要那么复杂:AccordionItem是为这种工作而设计的:

                    $view_uploads_sql = $db->prepare("SELECT file_name, file_id FROM uploads WHERE owner_id = ?");
                    $view_uploads_sql->execute(array($_SESSION['memberID']));

                    $upload_array = $view_uploads_sql->fetch();
                    echo array_values($t);
                    for ($i = 0; $i < count($upload_array); $i++)
                    {
                       echo "<a href = 'uploads/$upload_array[$i]'>$upload_array[$i]</a>";
                    }

Live example

这里的诀窍是sscanf为您提供了开始剪切所需的字符串宽度(sscanf($code, '%dc%32s%n', $length, $md5, $width); $number = substr($code, $width, $length); ),以及长度(从第一个{{1}开始) }),所以你拥有做简单字符串切割所需的一切。

答案 2 :(得分:1)

(\d+)添加到最后,就像开头一样。

/^(\d+)(c)(\w{32})(\d+)/

答案 3 :(得分:1)

/(\d)(c)([[:alnum:]]{32})(\d+)/
preg_match('/(\d)(c)([[:alnum:]]{32})(\d+)/', $string, $matches);
$the_number_of_digits = $matches[1];
$separator            = $matches[2];
$hashed_string        = $matches[3];
$number               = $matches[4];

然后,要检查$number的字符串长度是否等于$the_number_of_digits,您可以使用strlen,即:

if(strlen($number) ==  $the_number_of_digits){

}

与其他答案的主要区别在于使用[[:alnum:]],与\w不同,它不会与_匹配。

[:alnum:]
  

字母数字字符:'[:alpha:]'和'[:digit:]';在'C'中   locale和ASCII字符编码,这个是一样的   “[0-9A-Za-z]”。

http://www.gnu.org/software/grep/manual/html_node/Character-Classes-and-Bracket-Expressions.html

Regex101 Demo

Ideone Demo

正则表达式说明:

(\d)(c)([[:alnum:]]{32})(\d+)

Match the regex below and capture its match into backreference number 1 «(\d)»
   Match a single character that is a “digit” (any decimal number in any Unicode script) «\d»
Match the regex below and capture its match into backreference number 2 «(c)»
   Match the character “c” literally (case insensitive) «c»
Match the regex below and capture its match into backreference number 3 «([[:alnum:]]{32})»
   Match a character from the **POSIX** character class “alnum” (Unicode; any letter or ideograph, digit, other number) «[[:alnum:]]{32}»
      Exactly 32 times «{32}»
Match the regex below and capture its match into backreference number 4 «(\d+)»
   Match a single character that is a “digit” (any decimal number in any Unicode script) «\d+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»