Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fjerne streng fra en substreng

7 views
Skip to first unread message

Ronny A. Hansen

unread,
Feb 1, 2006, 12:20:31 PM2/1/06
to
Jeg har følgende eksempelstreng:
-e en -e "to -e tre -e fire -e fem -e seks -e syv" -e åtte

Denne vil jeg få på formatet:
-e en -e "to tre fire fem seks syv" -e åtte

Jeg vil med andre ord ha bort "-e" mellom de to anførselstegnene i denne
strengen. Antall felt innenfor anførselstegn varierer for øvrig (Hvilket
er det som gjør at en uerfaren perl-mann som meg kommer til kort).

Jeg har prøvd meg på noen variasjoner av typen:
s/(")(.* \-e .*)(")/$1$3/gi

Jeg har ikke kommet helt i mål og jeg lurer på om dette kan realiseres
ved regex eller om det må scriptes ytterligere.

For øvrig er problemstillingen at jeg lager min egen lille søkemotor for
en egen tabulatorseparert database og da vil skille mellom:

- enkeltord (bla)
- fraser ("bla bla bla")
- unntak (-bla)

Jeg trunkerer automatisk (ord og ord* er begge lik ord*).

Får jeg til problemet beskrevet er jeg vel så godt som i mål, men tar
gjerne i mot mer generelle tips til hvordan hele problemstillingen bør
løses.

På forhånd takk for hjelp :)

Ronny

Hallvard B Furuseth

unread,
Feb 2, 2006, 5:08:41 AM2/2/06
to
Ronny A. Hansen skriver:

(bytter om rekkefølgen litt)

> For øvrig er problemstillingen at jeg lager min egen lille søkemotor
> for en egen tabulatorseparert database og da vil skille mellom:
>
> - enkeltord (bla)
> - fraser ("bla bla bla")
> - unntak (-bla)
>
> Jeg trunkerer automatisk (ord og ord* er begge lik ord*).

Splitt opp input til en liste eller array av hver bit, noe a la:
('bla', '"bla -e bla -e bla"', '-bla')

gjør deretter det du vil med hver komponent, og sett dem så sammen
igjen:
join(" ", ('bla', '"bla bla bla"', '-bla'))

Med regex-hacking på hele inputstringen blir det alt for lett feil:

> Jeg har følgende eksempelstreng:
> -e en -e "to -e tre -e fire -e fem -e seks -e syv" -e åtte
>
> Denne vil jeg få på formatet:
> -e en -e "to tre fire fem seks syv" -e åtte

I akkurat det tilfellet kunne du bruke
0 while s/(\".*? )-e (.*?\")/$1$2/g;

Men hva om det er to strenger mellom? Eller kanskje hvis det
er en brukerfeil i input? F.eks


-e en -e "to" -e tre -e "fire"

blir med koden over til


-e en -e "to" tre "fire"

Et regexp som takler alle muligheter på riktig måte, om et slikt er
mulig, ville nok bli svært hårete. Og...

> Jeg har prøvd meg på noen variasjoner av typen:
> s/(")(.* \-e .*)(")/$1$3/gi

$1 er første ", $3 er andre ", og du kaster alt imellom.

Når du har såpass lite oversikt over regexps tror jeg ikke det er så
lurt at du prøver å bruke dem så mye foreløpig.

--
Hallvard B Furuseth email: h.b.fu...@usit.uio.no
USIT, University of Oslo phone: +47-22 85 28 13

Lars Haugseth

unread,
Feb 2, 2006, 5:45:08 AM2/2/06
to

* "Ronny A. Hansen" <ron...@hotmail.com> wrote:
|
| Jeg har følgende eksempelstreng:
| -e en -e "to -e tre -e fire -e fem -e seks -e syv" -e åtte
|
| Denne vil jeg få på formatet:
| -e en -e "to tre fire fem seks syv" -e åtte
|
| Jeg vil med andre ord ha bort "-e" mellom de to anførselstegnene i
| denne strengen. Antall felt innenfor anførselstegn varierer for øvrig
| (Hvilket er det som gjør at en uerfaren perl-mann som meg kommer til
| kort).
|
| Jeg har prøvd meg på noen variasjoner av typen:
| s/(")(.* \-e .*)(")/$1$3/gi
|
| Jeg har ikke kommet helt i mål og jeg lurer på om dette kan realiseres
| ved regex eller om det må scriptes ytterligere.

Antar det kan forekomme flere par med anførselstegn i strengen din?

Det er mulig dette kan løses med en regex, men isåfall vil jeg tro
den blir ganske uleselig. Defor ville jeg heller ha delt opp strengen
og jobbet på hver enkelt del.

Forslag:

# Eksempelstreng
my $query = '-e en -e "to -e tre -e fire -e fem -e seks -e syv" -e åtte';

# Del opp i biter med anførselstegn som separator
my @parts = split /"/, $query;

# Se på hver enkelt bit
for my $i (0..$#parts) {
# Fjern -e hvis vi er inne i anførselstegn
$qp[$i] =~ s/-e\s*(.*?)/$1/g if ($i % 2);
}

# Sett sammen bitene igjen
my $newquery = join '"', @parts;

Alternativt kan for-løkka skrives på C-måten:

for (my $i = 1; $i <= $#parts; $i += 2) {
$qp[$i] =~ s/-e\s*(.*?)/$1/g;
}

Noe kjappere, men mindre leselig, og dette blir neppe noen flaskehals
i applikasjonen din...

--
Lars Haugseth

"If anyone disagrees with anything I say, I am quite prepared not only to
retract it, but also to deny under oath that I ever said it." -Tom Lehrer

Ronny A. Hansen

unread,
Feb 3, 2006, 2:34:30 AM2/3/06
to
Takk for gode forslag.

Jeg snudde litt på problemstillingen og kom i mål med regex etter en hel
del prøving og feiling. Men som du sier, jeg har ikke kontroll og det
kan hende det fort blir feil her. Skal se litt på tipsene dine og
vurdere om jeg skal gjøre om på løsningen :)

Ronny

Ronny A. Hansen

unread,
Feb 3, 2006, 2:36:30 AM2/3/06
to
Takk for tips.

Jeg kom i mål med regex, men ser at jeg kanskje har forsøkt gjøre det
litt vanskelig for meg selv, og at løsningen min derfor muligens ikke er
så stødig som jeg trodde. Skal vurdere om jeg skal gjøre om på den.

Ronny

Ronny A. Hansen

unread,
Feb 3, 2006, 3:35:23 AM2/3/06
to
Hallvard B Furuseth wrote:
> Ronny A. Hansen skriver:
>
>>For øvrig er problemstillingen at jeg lager min egen lille søkemotor
>>for en egen tabulatorseparert database og da vil skille mellom:
>>
>>- enkeltord (bla)
>>- fraser ("bla bla bla")
>>- unntak (-bla)
>>
>>Jeg trunkerer automatisk (ord og ord* er begge lik ord*).
>
> Splitt opp input til en liste eller array av hver bit, noe a la:
> ('bla', '"bla -e bla -e bla"', '-bla')
>

Jeg tror regex'en min fungerer greit, men det du beskriver her er jo
egentlig kjernen av det jeg ønsker gjøre (og er MYE mer leselig). Når
en streng kan bestå av både enkeltord, fraser, og unntak, hvordan deler
jeg disse opp riktig i en array. Hos meg ble:

bla "bla bla bla" -bla

til

('bla', '"bla', 'bla', 'bla"', '-bla')

Noen tips? det virker som du mente dette burde være en enkel sak (Jeg
lærer litt mens jeg holder på med små-scripting og har sikkert oversett
noe, i tillegg til at perl-kunnskapene mine nok ennå er heller begrenset).

Hallvard B Furuseth

unread,
Feb 3, 2006, 2:58:45 PM2/3/06
to
Ronny A. Hansen writes:
>>>Jeg trunkerer automatisk (ord og ord* er begge lik ord*).
>> Splitt opp input til en liste eller array av hver bit, noe a la:
>> ('bla', '"bla -e bla -e bla"', '-bla')
>
> Jeg tror regex'en min fungerer greit, men det du beskriver her er jo
> egentlig kjernen av det jeg ønsker gjøre (og er MYE mer leselig). Når
> en streng kan bestå av både enkeltord, fraser, og unntak, hvordan deler
> jeg disse opp riktig i en array.

Litt vanskelig å svare på før du beskriver syntaksen mer nøyaktig.
F.eks. hvordan skriver brukeren en '"' som _ikke_ skal funke som
anførselstegn - '"' eller \" ? Eller er det ikke mulig?
Hvordan tolkes 'en"to tre" "fire fem"seks' ?

Uansett, kanskje en av funksjonene i Text::ParseWords eller
Text::Balanced passer deg. Se mansidene. Kan sikkert koke opp noe
regex-greier også.

--
Hallvard

Ronny A. Hansen

unread,
Feb 4, 2006, 4:01:56 AM2/4/06
to
Hallvard B Furuseth wrote:

> Uansett, kanskje en av funksjonene i Text::ParseWords eller
> Text::Balanced passer deg. Se mansidene. Kan sikkert koke opp noe
> regex-greier også.
>

Takk skal du ha. Jeg sjekker ut jeg :)

Ha ne fin helg.

0 new messages