Regex Gruppierung ausschließen

liquidbeats

Erfahrenes Mitglied
Guten Morgen,

Ich stehe gerade vor dem Problem das ich gerne eine Gruppe bspw. (<span>|<legend>) In einer Suche Ausschließen wollen würde. Mir geht es Primär darum verschachtelungen zu vermeiden, welche beim Filtern verschiebungen hervorhbringen würden.

Ein kleines Beispiel
HTML:
<span> 
    Text bal blubb
    <span>Weiterer Text</span>
</span>
Ich habe vor mich von Innen nach aussen zu graben. Andersrum würde ja folgendes bei rumkommen.
HTML:
<span> 
    Text bal blubb
    <span>Weiterer Text</span>
Sprich das letzte </span> würde verschluckt werden. Ich habe vieles Probiert, aber keine Lösung brachte mir wirklich den erfolg.

Evtl. hat jemand einen Lösungsvorschlag o.ä.?

Danke
Grüße
 
Das ist mit regulären Ausdrücken schwer falls nicht sogar gar nicht machbar. Gehe lieber die Zeichenkette lieber Zeichen für Zeichen (oder Tag für Tag) durch und sammele die geöffneten auf einem Stapel um sie in der korrekten Reihenfolge wieder zu schließen.
 
Zeichen für Zeichen?
So ganz Verstehe ich das nicht. Ich möchte nur den Text innerhalb von <span>..</span>. Ist darin weiterhin ein Span dann diesen ebenfalls Seperat rausholen.

Vlt. sollt ich Feierabend machen :confused: :)


Grüße
 
Gehe lieber die Zeichenkette lieber Zeichen für Zeichen (oder Tag für Tag) durch und sammele die geöffneten auf einem Stapel um sie in der korrekten Reihenfolge wieder zu schließen.
So habe ich das jetzt auch gelöst. Reguläre-Ausdrücke sind derart Agressiv das kaum ein weiterkommen möglich gewesen ist. Ich gehe Position für Position durch und Prüfe die in dem darin Liegenden HTML Teil neustartende Tags.
Funktioniert Problemlos (Habe es bis auf eine Tiefe von 10 getestet).

Man da hat mir der Schädel geraucht bei den zahlen :D

Grüße
 
Folgendes ist möglich:
PHP:
function getLineOffset( $linesArray, $offset )
{
	$sum = 0;
	var_dump($linesArray);
	foreach( $linesArray as $key => $lineArray ) {
		if( $sum+$lineArray[1] > $offset ) {
			return ++$key.':'.abs($sum-$offset+strlen($lineArray[0]));
		}
		$sum += $lineArray[1];
	}
	return false;
}

function tokenize( $str )
{
	$tokens = array();
	$openTags = array();
	$lines = preg_match_all('/\r\n|\r|\n/s', $str, $linesArray, PREG_OFFSET_CAPTURE);
	$lines = $linesArray[0];
	$parts = preg_split('@(</?[a-z]+[^>]*>)@s', $str, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE);
	$tokenType = 'CDATA';
	$partCount = count($parts);
	for( $i=0; $i<$partCount; $i++ ) {
		$part =& $parts[$i];
		switch( $tokenType ) {
			case 'CDATA':
				if( $part[0]{0} == '<' ) {
					if( $part[0]{1} != '/' ) {
						$tokenType = 'TAG_OPEN';
					} else {
						$tokenType = 'TAG_CLOSE';
					}
					$i--;
					continue;
				} else {
					$tokenType = 'CDATA';
					$tokens[] = array(
						$tokenType, $part[0]
					);
				}
				break;

			case 'TAG_OPEN':
				if( $part[0]{0} != '<' ) {
					$tokenType = 'CDATA';
					$i--;
					continue;
				}
				preg_match('@<([a-z]+)[^>]*>@', $part[0], $match);
				$openTags[] = $match[1];
				$tokens[] = array(
					$tokenType, $part[0]
				);
				$tokenType = 'CDATA';
				break;

			case 'TAG_CLOSE':
				if( $part[0]{0} != '<' ) {
					$tokenType = 'CDATA';
					$i--;
					continue;
				}
				preg_match('@</([a-z]+)[^>]*>@', $part[0], $match);
				if( $openTags[count($openTags)-1] == $match[1] ) {
					array_pop($openTags);
				} else {
					if( in_array($match[1], $openTags) ) {
						echo '<p>Error: closing tag for "'.$match[1].'" not allowed here; expecting "'.$openTags[count($openTags)-1].'" in '.getLineOffset($lines, $part[1]).'</p>';
					} else {
						echo '<p>Error: closing tag for "'.$match[1].'" not allowed here (no "'.$match[1].'" element opened) in '.getLineOffset($lines, $part[1]).'</p>';
					}
					return false;
				}
				$tokens[] = array(
					$tokenType, $part[0]
				);
				$tokenType = 'CDATA';
				break;			
		}
	}
	foreach( $openTags as $tag ) {
		echo '<p>Error: missing closing tag for "'.$tag.'" in '.count($lines).'</p>';
		return false;
	}
	return $tokens;
}

$str = '<p>
   Text bal blubb
   <span>Weiterer Text</span></span>
';
echo '<pre>' . htmlspecialchars(print_r(tokenize($str), true)) . '</pre>';
 
Zurück