preg_split () создает массив из одной строки вместо разделения на основе регулярных выражений - PullRequest
0 голосов
/ 19 сентября 2019

Кто-то может заметить это немедленно, но я ослеп по этому шаблону поиска и не уверен, что мне не хватает.

// test string
$stringToSplit = "I awoke in the dim light of the fire pit surrounded by daunting stone walls, my chest tight and my breath stolen by the creak of the heavy oak door opposite my bed. But it wasn’t my bed; that sack of feathers and the sheets of linen were unfamiliar to me. It was the place that my captor had left me. I found it strange, despite struggling against my bonds and having the memory of the cord tearing into my flesh, that no rip, no break of the skin remained. My hands were free, though; bits of rope—severed by a knife or a sword—lay on the floor beside me.";

//test split parameters
$split = '/["’“]?(A-Z)(((Mr|Ms|Mrs|Dr|Gen|Col|Maj|Capt|Lt|Sgt|Cpl|Pvt|Hon|Jr|Sr|St|Rev|Prof)\.\s+((?!\w{2,}[.?!][’\"]?\s+["’]?[A-Z]).))?)((?![.?!]["’]?\s+["’]?[A-Z]).)[.?!…—]+["’”]?/';

//split based on parameters
$splitText = preg_split($split, $stringToSplit);

//return split text
print_r($splitText);

Текущий вывод:

Array ( [0] => I awoke in the dim light of the fire pit surrounded by daunting stone walls, my chest tight and my breath stolen by the creak of the heavy oak door opposite my bed. But it wasn’t my bed; that sack of feathers and the sheets of linen were unfamiliar to me. It was the place that my captor had left me. I found it strange, despite struggling against my bonds and having the memory of the cord tearing into my flesh, that no rip, no break of the skin remained. My hands were free, though; bits of rope—severed by a knife or a sword—lay on the floor beside me. )

Желаемый результат:

Array ( [0] => I awoke in the dim light of the fire pit surrounded by daunting stone walls, my chest tight and my breath stolen by the creak of the heavy oak door opposite my bed.
[1] = > But it wasn’t my bed; that sack of feathers and the sheets of linen were unfamiliar to me. 
[2] = > It was the place that my captor had left me. 
[3] = > I found it strange, despite struggling against my bonds and having the memory of the cord tearing into my flesh, that no rip, no break of the skin remained.
[4] = > My hands were free, though; bits of rope—severed by a knife or a sword—lay on the floor beside me. )

Регулярное выражение сложное, потому что оно предназначено для того, чтобы найти эти шаблоны, чтобы можно было правильно разбить любую строку в тексте и не зацикливаться на сокращениях и окончаниях, которые не являются истинным окончаниемсегментХотя все правила не применяются к тексту образца, мне нужны эти правила для анализа любого данного образца.

В текущем виде код возвращает одну пару ключ / значение ключа 0 со значением, являющимсявся нерасщепленная строка.

Изменить, чтобы добавить: Я добавляю более крупный образец текста, в котором для ясности показаны причины некоторых правил из строки регулярного выражения.

$stringToSplit = "I awoke in the dim light of the fire pit surrounded by daunting stone walls, my chest tight and my breath stolen by the creak of the heavy oak door opposite my bed. But it wasn’t my bed; that sack of feathers and the sheets of linen were unfamiliar to me. It was the place that my captor had left me. I found it strange, despite struggling against my bonds and having the memory of the cord tearing into my flesh, that no rip, no break of the skin remained. My hands were free, though; bits of rope—severed by a knife or a sword—lay on the floor beside me. They must be sure that I won’t… can’t escape. “Good,” my captor said, stepping the rest of the way into the room. “You’ve awakened.” The way he said it sent tingles racing along my skin. Whereas I considered waking up a trivial matter, this man seemed to reflect upon the act with some reverence. The man’s cloak, his cowl draped over his hair and forehead, matched the drab gray of my prison’s walls, and a shadow cast over his face made it impossible to distinguish any of his features. His eyes, though, were obvious, and they must have caught the firelight because they glowed pale blue. “My family…” I started, inching away as if I could escape through the stone at my back. “They’ll pay whatever ransom you ask. Please, I beg—” “You waste your breath.” The man approached, but he stopped at the table halfway and lay upon it folded cloth. “I am not the one who keeps you here.” “But you serve him… her? You must reason with your master—” “I must do nothing,” he replied, laughing. “And your family might not want you in your condition. Have you smelled yourself lately?” “No,” I said flatly, and it wasn’t until the man had said something that I noticed I couldn’t smell the wood roasting in the fireplace, or anything else for that matter. My whole body was numb except for my head, which still ached. I recalled that he had bashed me in the head with a club, but I couldn’t piece together much else. “Why are you keeping me here?” “You’ll see.” He gestured at the table. “I suggest you change.” And he closed the door behind him. I stood there for a time, consumed with loathing and hatred for the man. I glanced at the fire and then at the table. When I studied the door from where I stood, I realized that it had no lock, and the place seemed unlike any cell I’d ever seen. No prisoner, for all I knew, had ever been treated to his own fireplace, stuffed mattress, or wash basin. And so, believing my chances of escape slim and without any available options, I stripped the tattered clothes from my body. The shirt—the one my father had bought for me, the fine silk one—couldn’t be salvaged. The pants, too, were in ribbons and came off easily.";

Ответы [ 2 ]

1 голос
/ 19 сентября 2019

Я немного упростил ваше регулярное выражение.Я также использовал отрицательный вид сзади, который может не поддерживаться, если вы используете это в браузере.

Но вы можете попробовать это.

(?<!Mr|Ms|Mrs|Dr|Gen|Col|Maj|Capt|Lt|Sgt|Cpl|Pvt|Hon|Jr|Sr|St|Rev|Prof\.)(?<!["”“'])[.!?]+(?!["“”'])

Протестировано в Google Chrome v76.0.3809.132 здесь , используя увеличенный образец текста, и кажется, что все работает правильно.

Особенности:

  • Совпадение точек
  • Не совпадают точки после Mr, Ms и т. Д.
  • Не соответствует точка между ",", ", '

Редактировать.

Решением для сохранения разделителей является использование положительного взгляда сзади после сопоставления точекс отрицательным взглядом сзади.

$regex = "/(?<=(?<!Mr|Ms|Mrs|Dr|Gen|Col|Maj|Capt|Lt|Sgt|Cpl|Pvt|Hon|Jr|Sr|St|Rev|Prof\.)(?<![\"”“'])[!?.](?![!?.])(?![\"“”']))/";

$subject = "your text here";

$result = preg_split($regex, $subject, 0, PREG_SPLIT_NO_EMPTY);
0 голосов
/ 19 сентября 2019

Если вы хотите разбить вашу строку на каждый период (как в примере, который вы показали), но не тогда, когда им предшествует Mr|Ms|Mrs..., вы можете просто сделать что-то вроде этого:

$stringToSplit = "I awoke in the dim light of the fire pit surrounded by daunting stone walls, my chest tight and my breath stolen by the creak of the heavy oak door opposite my bed. But it wasn’t my bed; that sack of feathers and the sheets of linen were unfamiliar to me. It was the place that my captor had left me. I found it strange, despite struggling against my bonds and having the memory of the cord tearing into my flesh, that no rip, no break of the skin remained. My hands were free, though; bits of rope—severed by a knife or a sword—lay on the floor beside me. They must be sure that I won’t… can’t escape. “Good,” my captor said, stepping the rest of the way into the room. “You’ve awakened.” The way he said it sent tingles racing along my skin. Whereas I considered waking up a trivial matter, this man seemed to reflect upon the act with some reverence. The man’s cloak, his cowl draped over his hair and forehead, matched the drab gray of my prison’s walls, and a shadow cast over his face made it impossible to distinguish any of his features. His eyes, though, were obvious, and they must have caught the firelight because they glowed pale blue. “My family…” I started, inching away as if I could escape through the stone at my back. “They’ll pay whatever ransom you ask. Please, I beg—” “You waste your breath.” The man approached, but he stopped at the table halfway and lay upon it folded cloth. “I am not the one who keeps you here.” “But you serve him… her? You must reason with your master—” “I must do nothing,” he replied, laughing. “And your family might not want you in your condition. Have you smelled yourself lately?” “No,” I said flatly, and it wasn’t until the man had said something that I noticed I couldn’t smell the wood roasting in the fireplace, or anything else for that matter. My whole body was numb except for my head, which still ached. I recalled that he had bashed me in the head with a club, but I couldn’t piece together much else. “Why are you keeping me here?” “You’ll see.” He gestured at the table. “I suggest you change.” And he closed the door behind him. I stood there for a time, consumed with loathing and hatred for the man. I glanced at the fire and then at the table. When I studied the door from where I stood, I realized that it had no lock, and the place seemed unlike any cell I’d ever seen. No prisoner, for all I knew, had ever been treated to his own fireplace, stuffed mattress, or wash basin. And so, believing my chances of escape slim and without any available options, I stripped the tattered clothes from my body. The shirt—the one my father had bought for me, the fine silk one—couldn’t be salvaged. The pants, too, were in ribbons and came off easily.";

$split = preg_split('/(?:(?<!Mr|Ms|Mrs|Dr|Gen|Col|Maj|Capt|Lt|Sgt|Cpl|Pvt|Hon|Jr|Sr|St|Rev|Prof)\.|[!?)"])/', iconv('UTF-8', 'ASCII//TRANSLIT', $stringToSplit));

var_dump(array_filter(array_map('trim', $split))); // I've used array_map to trim any white spaces and then array filter remove empty array elements

РЕДАКТИРОВАТЬ: Чтобы разделить периоды, но не тогда, когда им предшествует Mr|Ms|Mrs..., просто используйте регулярное выражение negative lookbehind.

Дайте мне знать, может ли это быть полезным для вас сейчас.

...