Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php preg_split a text without loose ,.: and so forth

I try to split a text with preg_split(), but I don't get the regex for it.

example:

I search 1, regex to:  no. Or... yes!

should get:

Array
(
    [0] => I
    [1] => search
    [2] => 1
    [3] => ,
    [4] => regex
    [5] => to
    [6] => :
    [7] => no
    [8] => .
    [9] => Or
    [10] => ...
    [11] => yes
    [12] => !
)

I trylied the following code:

preg_split(
    "/([\s]+)/",
    "I search 1, regex to:  no. Or... yes!"
)

which end in:

Array
(
    [0] => I
    [1] => search
    [2] => 1,
    [3] => regex
    [4] => to:
    [5] => no.
    [6] => Or...
    [7] => yes!
)

EDIT: Ok, the original question was solved, but I forgot something in my example:

new example:

I search 1, regex (regular expression) to: That's it is! Und über den Wolken müssen wir...

should get:

array (
  0 => 'I',
  1 => 'search',
  2 => '1',
  3 => ',',
  4 => 'regex',
  5 => '(',
  6 => 'regular',
  7 => 'expression',
  8 => ')',
  9 => 'to',
  10 => ':',
  11 => 'That',
  12 => '\'s',
  13 => 'it',
  14 => 'is',
  15 => '!',
  16 => 'Und',
  17 => 'über',
  18 => 'den',
  19 => 'Wolken',
  20 => 'müssen',
  21 => 'wir',
  22 => '...',
)

one thing is, that the opening ( get not matched in the first solution. A other thing is, that also not the german chars ÄÖÜäöüß inside a word get not matched.

My last try was the following, which doesn't match:

\s+|(?<!(A-Za-z1-0ÄÖÜäöüß)+)(?=(A-Za-z1-0ÄÖÜäöüß)+)
like image 897
Thomas Avatar asked Jul 31 '26 08:07

Thomas


2 Answers

You can use this lookahead based regex:

$str = 'I search 1, regex to: no. Or... yes!';
$tok = preg_split('/\h+|(?<!\W)(?=\W)/', $str);

print_r($tok);

Array
(
    [0] => I
    [1] => search
    [2] => 1
    [3] => ,
    [4] => regex
    [5] => to
    [6] => :
    [7] => no
    [8] => .
    [9] => Or
    [10] => ...
    [11] => yes
    [12] => !
)

/\h+|(?<!\W)(?=\W) is alternation based regex which is splitting on 1+ horizontal space OR at a position where previous character is not a non-word char and next char is a non-word char.

RHS of alternation is (?<!\W)(?=\W) where (?<!\W) is negative lookbehind which means previous char is not a non-word char. Then (?=\W) is positive lookahead which means next char is a non-word char.

like image 157
anubhava Avatar answered Aug 01 '26 20:08

anubhava


I think apart from the 's bit that you seem to want as one piece – which doesn’t make that much sense to me, since for other punctuation chars such as ! or , you want individual parts – you could do it by simply splitting at any whitespace or word boundary,

preg_split(
  '#\s|\b#u',
  "I search 1, regex (regular expression) to: That's it is! Und über den Wolken müssen wir...",
  -1,
  PREG_SPLIT_NO_EMPTY
);
like image 23
CBroe Avatar answered Aug 01 '26 20:08

CBroe