动态检测字符串中的选项数

时间:2016-11-20 11:37:25

标签: php regex

我试图通过正则表达式动态检测来自具有不同数量选项的问题的选项。问题可能有选择,直到b,c,e或f,g ....当前的例子直到d。

1. Which two OSI model layers have the same functionality as two layers of the TCP/IP model? (Choose two.)
a. data link
a. network*
a. physical
a. session

PHP - 我尝试过的。这仅检测4个选项,如果我添加第5个或第6个选项,或者如果我删除它,它将无法工作。

$textarea = preg_match_all('#\d+\.\s(.*)\s*[a-zA-Z]\.\s(.*?)\s*(.*)\s*[a-zA-Z]\.\s(.*?)\s*(.*)\s*[a-zA-Z]\.\s(.*?)\s*(.*)\s*[a-zA-Z]\.\s(.*?)\s*(.*)\s*#i', $textarea, $matches);

Array
(
    [0] => Array
        (
            [0] => 1. Which two OSI model layers have the same functionality as two layers of the TCP/IP model? (Choose two.)
a. data link
a. network*
a. physical
a. session
        )

    [1] => Array
        (
            [0] => Which two OSI model layers have the same functionality as two layers of the TCP/IP model? (Choose two.)
        )

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

    [3] => Array
        (
            [0] => data link
        )

    [4] => Array
        (
            [0] => 
        )

    [5] => Array
        (
            [0] => network*
        )

    [6] => Array
        (
            [0] => 
        )

    [7] => Array
        (
            [0] => physical
        )

    [8] => Array
        (
            [0] => 
        )

    [9] => Array
        (
            [0] => session
        )

)

REGEX ONLINE

http://regexr.com/3en2b

2 个答案:

答案 0 :(得分:2)

具有生成器功能的示例:

让我们说你有这个字符串:

$txt = <<<'EOD'
1. What is your name?
a. Theresa
b. Mike
c. Jugurtha
d. I don't know

2. What is your favorite animal?
a. Rabbit
b. Dog
c. Cat
d. Poney
e. Unicorn
EOD;

生成器功能:

function getQuestionAnswers($fh) {
    while (false !== $line = fgets($fh)) {
        if (preg_match('~^(?:(?<Qno>[0-9]+)|(?<Ano>[a-z]+))\. (?<content>.*)~', $line, $m)) {
            if ($m['Ano']) {
                $result['answers'][] = ['no' => $m['Ano'], 'content' => $m['content']];
            } else {
                if (isset($result))
                    yield $result;

                $result = [
                    'question' => [
                        'no' => $m['Qno'],
                        'content' => $m['content']
                    ]
                ];
            }
        }
    }
    if (isset($result))
        yield $result;
}

如何使用它:

$fh = fopen('data:text/plain;base64,' . base64_encode($txt), 'rb');

foreach (getQuestionAnswers($fh) as $qas) {
    printf("Question number %d with %d answers\n", $qas['question']['no'], count($qas['answers']));
}

fclose($fh);

答案 1 :(得分:1)

试试这个简单的正则表达式:#(.?)\.\s(.*)(\n|$)#im

$textarea = <<<LINES
1. Which two OSI model layers have the same functionality as two layers of the TCP/IP model? (Choose two.)
a. data link
b. network*
c. physical
d. session
e. test1

2. Question 2
a. link
b. net*
c. phys
d. ses
e. tst
LINES;

$questions = preg_split('#\n[\\n]+#', $textarea);

echo "Questions: \n";
print_r($questions);

echo "--------------------------\n";

//if($found = preg_match_all('#(.?)\.\s(.*)(\n|$)#im', $textarea, $matches)) {

foreach($questions as $question) {
    //if($found = preg_match_all('#((.?)\.\s(.*)(\n|$))|(?=\s*^\s*$)#smx', $question, $matches)) {
    if($found = preg_match_all('#(.?)\.\s(.*)(\n|$)#im', $question, $matches)) {
        echo "Q ".$matches[1][0].': '.$matches[2][0]."'\n";

        for($i = 1; $i < $found; $i++) {
            echo "  A {$i}: '".$matches[1][$i]."', '".$matches[2][$i]."'\n";
        }
    }
}

<强>输出

Questions: 
Array
(
    [0] => 1. Which two OSI model layers have the same functionality as two layers of the TCP/IP model? (Choose two.)
a. data link
b. network*
c. physical
d. session
e. test1
    [1] => 2. Question 2
a. link
b. net*
c. phys
d. ses
e. tst
)
--------------------------
Q 1: Which two OSI model layers have the same functionality as two layers of the TCP/IP model? (Choose two.)'
  A 1: 'a', 'data link'
  A 2: 'b', 'network*'
  A 3: 'c', 'physical'
  A 4: 'd', 'session'
  A 5: 'e', 'test1'
Q 2: Question 2'
  A 1: 'a', 'link'
  A 2: 'b', 'net*'
  A 3: 'c', 'phys'
  A 4: 'd', 'ses'
  A 5: 'e', 'tst'

<强>更新

如果你想在一个字符串中有多个问题,那么你应该首先拆分字符串的空行,并将所有问题存储在一个数组中,如下所示:

$questions = preg_split('#\n[\\n]+#', $textarea);

请参阅上面的更新代码以获取完整示例。